web-dev-qa-db-ja.com

iOS:Swift-タッチで地図にピンポイントを追加してその場所の詳細な住所を取得する方法は?

IOSマップをタッチしてアノテーションを追加し、それぞれの場所の詳細な住所(目印)を取得したい。 Swiftでこれを実現するにはどうすればよいですか?

前もって感謝します。

18
SRK

地図のタッチに反応するには、mapViewのタップ認識機能を設定する必要があります

viewDidLoad

let gestureRecognizer = UITapGestureRecognizer(target: self, action:"handleTap:")
    gestureRecognizer.delegate = self
    mapView.addGestureRecognizer(gestureRecognizer)

タップを処理して、タップされた場所の座標を取得します。

func handleTap(gestureRecognizer: UILongPressGestureRecognizer) {

    let location = gestureRecognizer.locationInView(mapView)
    let coordinate = mapView.convertPoint(location, toCoordinateFromView: mapView)

    // Add annotation:
    let annotation = MKPointAnnotation()
    annotation.coordinate = coordinate
    mapView.addAnnotation(annotation)
}

これで、注釈を描画するためにMKMapViewデリゲート関数を実装するだけで済みます。単純なグーグル検索はあなたにそれの残りを得るはずです。

22
Moriya

これは、Xcode 10.1、Swift 4.2プロジェクトMapKitデリゲート注釈(ピンの色、ピン画像など)を制御し、追加された注釈のクリックを処理する委任: Github Project

import UIKit
import MapKit

class ViewController: UIViewController {

@IBOutlet weak var mapView: MKMapView!

override func viewDidLoad() {
    super.viewDidLoad()
    mapView.delegate = self
    let longTapGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
    mapView.addGestureRecognizer(longTapGesture)
}

@objc func longTap(sender: UIGestureRecognizer){
    print("long tap")
    if sender.state == .began {
        let locationInView = sender.location(in: mapView)
        let locationOnMap = mapView.convert(locationInView, toCoordinateFrom: mapView)
        addAnnotation(location: locationOnMap)
    }
}

func addAnnotation(location: CLLocationCoordinate2D){
        let annotation = MKPointAnnotation()
        annotation.coordinate = location
        annotation.title = "Some Title"
        annotation.subtitle = "Some Subtitle"
        self.mapView.addAnnotation(annotation)
}
}

extension ViewController: MKMapViewDelegate{

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    guard annotation is MKPointAnnotation else { print("no mkpointannotaions"); return nil }

    let reuseId = "pin"
    var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView

    if pinView == nil {
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        pinView!.canShowCallout = true
        pinView!.rightCalloutAccessoryView = UIButton(type: .infoDark)
        pinView!.pinTintColor = UIColor.black
    }
    else {
        pinView!.annotation = annotation
    }
    return pinView
}

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    print("tapped on pin ")
}

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    if control == view.rightCalloutAccessoryView {
        if let doSomething = view.annotation?.title! {
           print("do something")
        }
    }
  }
}
8
Peter Pohlmann

スウィフト4:

 @IBOutlet weak var mapView: MKMapView!

 func handleLongPress (gestureRecognizer: UILongPressGestureRecognizer) {
    if gestureRecognizer.state == UIGestureRecognizerState.began {
        let touchPoint: CGPoint = gestureRecognizer.location(in: mapView)
        let newCoordinate: CLLocationCoordinate2D = mapView.convert(touchPoint, toCoordinateFrom: mapView)
        addAnnotationOnLocation(pointedCoordinate: newCoordinate)
    }
}

func addAnnotationOnLocation(pointedCoordinate: CLLocationCoordinate2D {
    let annotation = MKPointAnnotation()
    annotation.coordinate = pointedCoordinate
    annotation.title = "Loading..."
    annotation.subtitle = "Loading..."
    mapView.addAnnotation(annotation)
}
2
Sat

Swift 4の場合、Swift 3の例を他のSwift 4のように変換したので、私にはうまくいきませんでした:(I m他のコードに合わせるために、 'mapView'ではなく 'mapview'を使用する

        let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
        gestureRecognizer.delegate = self
        mapview.addGestureRecognizer(gestureRecognizer)


@objc func handleTap(_ gestureReconizer: UILongPressGestureRecognizer)
    {

        let location = gestureReconizer.location(in: mapview)
        let coordinate = mapview.convert(location,toCoordinateFrom: mapview)

        // Add annotation:
        let annotation = MKPointAnnotation()
        annotation.coordinate = coordinate
        mapview.addAnnotation(annotation)
    }
1
SundialSoft
 //put this in viewdidload

-->
 mapView.delegate = self
           let longTapGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
           mapView.addGestureRecognizer(longTapGesture)
    -->//

@objc func longTap(sender: UIGestureRecognizer){
    print("long tap")
    if sender.state == .began
    {
        let locationInView = sender.location(in: mapView)
        let locationOnMap = mapView.convert(locationInView, toCoordinateFrom: mapView)
        addAnnotation(location: locationOnMap)
        locationManager.stopUpdatingLocation();
        print("the location lattitude is = \(locationOnMap.latitude) and logitude on map = \(locationOnMap.longitude)")
        self.passlat = Double(locationOnMap.latitude)
        self.passlong = Double(locationOnMap.longitude)
        self.getAddressFromLatLon(pdblLatitude: "\(locationOnMap.latitude)", withLongitude: "\(locationOnMap.longitude)")

    }
}


func getAddressFromLatLon(pdblLatitude: String, withLongitude pdblLongitude: String)
{
    var center : CLLocationCoordinate2D = CLLocationCoordinate2D()
    let lat: Double = Double("\(pdblLatitude)")!
    //21.228124
    let lon: Double = Double("\(pdblLongitude)")!
    //72.833770
    let ceo: CLGeocoder = CLGeocoder()
    center.latitude = lat
    center.longitude = lon

    let loc: CLLocation = CLLocation(latitude:center.latitude, longitude: center.longitude)


    ceo.reverseGeocodeLocation(loc, completionHandler:
        {(placemarks, error) in
            if (error != nil)
            {
                print("reverse geodcode fail: \(error!.localizedDescription)")
            }
            let pm = placemarks! as [CLPlacemark]
            if pm.count > 0
            {
                let pm = placemarks![0]
               // print(pm.country)
                //print(pm.locality)
                self.mapaddcontry = pm.country!
                self.mapaddrState = pm.subLocality!
                self.mapaddrcity = pm.locality!
                self.mapaddrPincode = pm.postalCode!

                self.mainname = pm.locality!
                print(pm.subLocality)
                self.subname = pm.subLocality!
                print(pm.thoroughfare)
                print(pm.postalCode)
                print(pm.subThoroughfare)
                var addressString : String = ""
                if pm.subLocality != nil
                {
                    addressString = addressString + pm.subLocality! + ", "
                }
                if pm.thoroughfare != nil {
                    addressString = addressString + pm.thoroughfare! + ", "
                }
                if pm.locality != nil {
                    addressString = addressString + pm.locality! + ", "
                }
                if pm.country != nil
                {
                    addressString = addressString + pm.country! + ", "
                }
                if pm.postalCode != nil
                {
                    addressString = addressString + pm.postalCode! + " "
                }

                self.addr.text = addressString
                print(addressString)
                self.mapaddrtxt.text = addressString
                self.location_name = addressString

            }
    })

}
0
kiran

For Swift 3.の場合

let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
gestureRecognizer.delegate = self
mapView.addGestureRecognizer(gestureRecognizer)

func handleTap(_ gestureReconizer: UILongPressGestureRecognizer) {

    let location = gestureReconizer.locationInView(mapView)
    let coordinate = mapView.convertPoint(location,toCoordinateFromView: mapView)

    // Add annotation:
    let annotation = MKPointAnnotation()
    annotation.coordinate = coordinate
    mapView.addAnnotation(annotation)
}
0
Andre Lara

他の回答はタッチイベントの処理方法を適切にカバーしているため、次のステップはCLGeocoderを使用して逆ジオコーディングを実行し、位置の値をその位置の目印のリストに変換します。

func handleTap(gestureReconizer: UILongPressGestureRecognizer) {

    let location = gestureReconizer.locationInView(mapView)
    let coordinate = mapView.convertPoint(location,toCoordinateFromView: mapView)

    let geocoder = CLGeocoder()
    geocoder.reverseGeocodeLocation(coordinate) { (placemarks, error) in 
        if let places = placemarks {
            for place in places {
                print("found placemark \(place.name) at address \(place.postalAddress)"
            }
        }
    }
}
0
Devin Lane