如何将按钮添加到 Swift 中的 MKPointAnnotation

How do I add button to MKPointAnnotation in Swift

我想添加一个按钮,当用户点击标记时,该按钮将出现在注释的右侧。这是我目前正在做的事情。

  1. 从我的网站下载 json 文件。
  2. 打开文件并解析它。
  3. 使用 json 文件
  4. 中的坐标绘制所有标记
  5. 但是现在..如何在我的注释右侧添加一个按钮,当用户点击它时会移动到 detailViewController?

这是我的 ViewDidLoad

//Retrieve the existing JSON from document directory
        let defaults = UserDefaults.standard
        let fileUrl = defaults.url(forKey: "pathForJSON")
        do {
            let jsonData = try Data(contentsOf: fileUrl!, options: [])
            let myJson = try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as! [Dictionary<String,AnyObject>]
            // print out the content
//            print("My JSON: ", myJson)
            createAnnotation(locations: myJson)
        } catch {
            print(error)
        }

我的 createAnnotation 函数。

func createAnnotation(locations: [Dictionary<String, AnyObject>]) {
        for location in locations {
            let annotation = MKPointAnnotation()
            annotation.title = location["name"] as? String
            let lat = (location["latitude"] as! NSString).doubleValue
            let lon = (location["longitude"] as! NSString).doubleValue
            annotation.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
            mapView.addAnnotation(annotation)
//            print(annotation)
        }
    }

试试下面的代码

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        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

        let rightButton: AnyObject! = UIButton(type: UIButton.ButtonType.detailDisclosure)
        pinView?.rightCalloutAccessoryView = rightButton as? UIView
    }
    else {
        pinView?.annotation = annotation
    }

    return pinView
}

不要忘记设置 mapView 的委托

mapView.delegate = self

顺便说一下,如果目标是 iOS 11 或更高版本,您可以进一步简化它,特别是:

  • 完全删除你的mapView(_:viewFor:)

  • 注册默认注释视图class;

  • 定义注释视图class,根据需要配置注释及其标注。

例如:

class CustomAnnotationView: MKPinAnnotationView {
    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        canShowCallout = true
        rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

并且,在您的视图控制器中:

override func viewDidLoad() {
    super.viewDidLoad()

    mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
}