Swift MKMapView 引脚注释问题

Posted

技术标签:

【中文标题】Swift MKMapView 引脚注释问题【英文标题】:Swift MKMapView Pin Annotation Issue 【发布时间】:2017-07-01 19:23:04 【问题描述】:

我正在尝试使用预设搜索参数在地图上显示图钉。单击按钮,该应用程序将显示所有本地出租车服务。那部分我记下来了……我有附加到[MKPointAnnotation] 的项目,它成功地在tableView 中显示了一个填充列表以及mapView 上的引脚。出于某种原因,当您点击mapView 上的图钉时,我无法显示标题和副标题,即使在实现viewFor annotation: 委托时也是如此。有什么想法吗?

class MapViewController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource, UITableViewDelegate, MKMapViewDelegate 

@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var tableView: UITableView!

let locationManager = CLLocationManager()
let regionRadius: CLLocationDistance = 1500
var matchingItems: [MKMapItem] = [MKMapItem]()
var annotationGroup = [MKPointAnnotation]()

override func viewDidLoad() 
        super.viewDidLoad()
        locationManager.delegate = self
        tableView.delegate = self
        tableView.dataSource = self
        mapView.delegate = self


        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.allowsSelection = true


        let currentLocation = locationManager.location
        guard let latitude = currentLocation?.coordinate.latitude,
            let longitude = currentLocation?.coordinate.longitude else 
                alertPopup(title: "Enable Location Services", message: "Navigate to Settings >", buttonTitle: "Ok")
                return
        
        let initialLocation = CLLocation(latitude: latitude, longitude: longitude)
        tabBarController?.tabBar.isHidden = true
        centerMapOnLocation(location: initialLocation)

        let request = MKLocalSearchRequest()
        request.naturalLanguageQuery = "Taxi"
        request.region = mapView.region

        let search = MKLocalSearch(request: request)

        search.start(completionHandler: (response, error) in

            if error != nil 
                print("Error occured in search: \(error!.localizedDescription)")
             else if response!.mapItems.count == 0 
                print("No Matches Found")
             else 
                print("Matches Found")
            

            for location in response!.mapItems 
                print("Name = \(String(describing: item.name))")
                print("Phone = \(String(describing: item.phoneNumber))")
                self.matchingItems.append(item)

                var pinAnnotationView = MKPinAnnotationView()
                let annotation = MKPointAnnotation()
                annotation.coordinate.longitude = location.placemark.coordinate.longitude
                annotation.coordinate.latitude = location.placemark.coordinate.latitude
                annotation.title? = location.name!
                annotation.subtitle = location.phoneNumber!
                self.annotationGroup.append(annotation)
                self.mapView.addAnnotations(self.annotationGroup)
                pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
                self.mapView.addAnnotation(pinAnnotationView.annotation!)
            
            self.tableView.reloadData()
            print("Reloaded Table Data")
            print(self.matchingItems)
            self.mapView.showAnnotations(self.annotationGroup, animated: true)

        )
    

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 

        if !(annotation is MKUserLocation) 
            let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))

            let rightButton = UIButton(type: .contactAdd)
            rightButton.tag = annotation.hash

            pinView.animatesDrop = true
            pinView.canShowCallout = true
            pinView.rightCalloutAccessoryView = rightButton

            return pinView
         else 
            print("Returned nil")
            return nil
        

    

【问题讨论】:

我认为问题在于您没有直接向self.mapView添加注释。相反,您将其添加到 self.annotationGroup。你没有解释它是什么。 @El Tomato annotationGroup 是在 MapViewController 类开头声明的注释数组,我将注释附加到循环中。我将注释数组添加到mapView..self.mapView.addAnnotations(self.annotationGroup. 【参考方案1】:

问题是可选的annotation.title? = location.name!。删除可选的,它可以工作。

    for location in response!.mapItems 
        print("Name = \(String(describing: location.name))")
        print("Phone = \(String(describing: location.phoneNumber))")
        self.matchingItems.append(location)
        let annotation = MKPointAnnotation()
        annotation.coordinate.longitude = location.placemark.coordinate.longitude
        annotation.coordinate.latitude = location.placemark.coordinate.latitude
        annotation.title = location.name!  //This is the line to remove the optional annotation.title? from.
        annotation.subtitle = location.phoneNumber!
        self.annotationGroup.append(annotation)
        self.mapView.addAnnotations(self.annotationGroup)
        self.mapView.showAnnotations(self.annotationGroup, animated: true)
        

【讨论】:

【参考方案2】:

也许为时已晚,但无论如何

首先,MKAnnotation 是一个协议,所以我认为你必须为你的对象定义一个自定义类,并且这个类必须实现这个协议,或者在这种情况下,我们可以为 MKMapItem 定义一个扩展,实现 @987654323 @协议

extension MKMapItem : MKAnnotation

  public var coordinate: CLLocationCoordinate2D 
    return self.placemark.coordinate
  


  // Title and subtitle for use by selection UI.
  public var title: String? 
    return self.name
  

  public var subtitle: String? 
    return self.phoneNumber
  

有了这个你的代码将被简化为这个

search.start(completionHandler: (response, error) in

            if error != nil 
                print("Error occured in search: \(error!.localizedDescription)")
             else if response!.mapItems.count == 0 
                print("No Matches Found")
             else 
                print("Matches Found")
            

            for location in response!.mapItems 
                print("Name = \(String(describing: item.name))")
                print("Phone = \(String(describing: item.phoneNumber))")
                self.matchingItems.append(item)
            
          self.mapView.addAnnotations(self.matchingItems)
            self.tableView.reloadData()
            print("Reloaded Table Data")
            print(self.matchingItems)
            self.mapView.showAnnotations(self.matchingItems, animated: true)
        )

一旦你有了这个,那么你对func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 的实现应该可以工作了

希望对你有帮助

【讨论】:

以上是关于Swift MKMapView 引脚注释问题的主要内容,如果未能解决你的问题,请参考以下文章

标注在 MKMapView - iPhone 的引脚后面弹出

当我在 mkMapView 中更改段时无法更改引脚颜色

添加自定义注释引脚

多个注释数组,每个数组的引脚颜色不同?

Swift - 将不同的图像从数组设置到注释引脚

带有 MKMapKit 的 Swift GestureRecognizers - 放置引脚并拖动