我正在使用MapView,在其中单击任何自定义注释图钉时,将显示自定义标注视图(从xib文件加载)。

从这个自定义标注中,我有一个UIButton,我已经可以检测到对此按钮的单击,但是我想像基本标注中的:view?.rightCalloutAccessoryView一样在Map上进行访问。

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView,  {

    if view.annotation!.isKind(of: MKUserLocation.self){
        return
    }

    let customView = (Bundle.main.loadNibNamed("CustomCalloutView", owner: self, options: nil))?[0] as! CustomCalloutView;
    let calloutViewFrame = customView.frame;
    customView.frame = CGRect(x: -calloutViewFrame.size.width/2.23, y: -calloutViewFrame.size.height+10, width: 315, height: 170)

    view.addSubview(customView)

    let region = MKCoordinateRegion(center: pinToZoomOn!.coordinate, span: span)

    mapView.setRegion(region, animated: true)
}


该路线是从经典标注正确计算得出的,但我不知道如何通过自定义标注的按钮访问地图。

我的CustomCalloutViewClass:

import UIKit
import MapKit

class CustomCalloutView: MKAnnotationView {

@IBOutlet weak var goButton: UIButton!

@IBAction func goButton(_ sender: AnyObject) {
    print("Button clicked sucessfully")
}

// MARK: - Detect taps on callout

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    let hitView = super.hitTest(point, with: event)
    if hitView != nil {
        superview?.bringSubview(toFront: self)
    }
    return hitView
}

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    let rect = self.bounds
    var isInside = rect.contains(point)
    if !isInside {
        for view in subviews {
            isInside = view.frame.contains(point)
            if isInside {
                break
            }
        }
    }
    return isInside
}
}


如果有人有想法,那将对我有所帮助。

先感谢您。

最佳答案

选项1:在传递给CustomCalloutView的闭包中捕获MKMapView实例

添加将在按钮操作上调用的闭包。该闭包将捕获MKMapView实例,您将可以在其中找到我们。

class CustomCalloutView: MKAnnotationView {
    var didTapGoButton: (() -> Void)?

    @IBAction func goButton(_ sender: AnyObject) {
        didTapGoButton?()
    }
}


选项2:将对MKMapView的弱引用添加为标注的属性

这不是一个干净的解决方案,但在某些情况下可能是一个选择。您只需要创建一个弱属性即可在MKMapView中存储对CustomCalloutView实例的引用

class CustomCalloutView: MKAnnotationView {
    weak var mapView: MKMapView?
}


组态

这是为两种解决方案连接CustomCalloutView的方式。记住要使用快速捕获列表来捕获对MKMapView实例的弱引用。没有它,您可能会创建一个强大的参考周期。

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)  {
    // ...
    let customView = (Bundle.main.loadNibNamed("CustomCalloutView", owner: self, options: nil))?[0] as! CustomCalloutView;
    // Option 1
    customView.didTapGoButton = { [weak mapView ] in
        print(mapView?.annotations.count)
    }
    // Option 2
    customView.mapView = mapView
    // ...
}

关于ios - 自定义标注 View 按钮以映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46989663/

10-13 03:40