MapKit iOS 9 detailCalloutAccessoryView 用法

MapKit iOS 9 detailCalloutAccessoryView usage

看完后 WWDC video 206 我认为将细节标注视图添加到 mapView 注释视图是一项微不足道的任务。

所以,我假设我做错了什么。

我的图钉视图已设置好

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    let view:MKAnnotationView!

    if let dequed = routeMapView.dequeueReusableAnnotationViewWithIdentifier("pin") {
        view = dequed
    }
    else {
        view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
    }

    let x = UIView(frame: CGRectMake(0, 0, 200, 200))
    x.backgroundColor = UIColor.redColor()

    // shows the red
    //view.leftCalloutAccessoryView = x

    // working as no subtitle - but no red view
    view.detailCalloutAccessoryView = x

    view.canShowCallout = true
    return view
}

我只知道这个

我知道该视图有效,因为如果我尝试使用 leftCalloutAccessoryView 我会得到

我一定是漏掉了什么。请注意,如果我只是将图像添加到 detailCalloutAccessoryView 中,例如

view.detailCalloutAccessoryView = UIImage(named:"YourImageName")

图像存在,大小正确等

我只是不知道如何放入我自己的自定义视图。

谢谢

使用 UIImageView

view.detailCalloutAccessoryView = UIImageView(image:UIImage(named:"YourImageName")) 

1.创建一个 UIView 并将其添加到 Storyboard

中的地图 VC

您可以在此处设置大小、约束、添加按钮、图像等 - 布局如您所愿。堆栈视图在这种情况下工作完美。

2。创建并发布到您的地图 VC

像往常一样从您的自定义视图控制拖动。

@IBOutlet var customDetailView: UIView!

3。为您的 pin

设置 detailCalloutAccessoryView

例如

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    view.detailCalloutAccessoryView = customDetailView
}

成功

您必须为视图的宽度和高度添加一些约束:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    var av = mapView.dequeueReusableAnnotationViewWithIdentifier("id")
    if av == nil {
        av = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "id")
    }

    let myView = UIView()
    myView.backgroundColor = .greenColor()

    let widthConstraint = NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 40)
    myView.addConstraint(widthConstraint)

    let heightConstraint = NSLayoutConstraint(item: myView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 20)
    myView.addConstraint(heightConstraint)

    av!.detailCalloutAccessoryView = myView
    av!.canShowCallout = true

    return av!
}

添加 intrinsicContentSize 也有效。

我做了一些测试,发现当您将视图设置为 detailCalloutAccessoryView.

时,MapKit 会自动将 translatesAutoresizingMaskIntoConstraints 设置为 false

在 WWDC 2015 session "What's New in MapKit" 中,有人说 "auto layout is supported"。我估计 Apple 的意思是,你必须使用自动布局?!

您可以使用自定义 class 并覆盖 intrinsicContentSize 以根据其子内容动态调整详细视图的大小。 (正如@Klaas 在 中所暗示的那样)

如果您的视图大小事先未知或在运行时确实发生变化,或者您只是不想以编程方式添加约束,这可能特别有用。

这是一个使用堆栈视图内的两个标签的示例。 intrinsicContentSize 设置为等于堆栈视图将采用的大小。将以下实例设置为 detailAccessoryView 应该会让您获得一个对标签文本中的更改做出反应并且不需要以编程方式添加约束的视图。

class CustomCalloutDetailView : UIView {

    @IBOutlet weak var label1: UILabel!

    @IBOutlet weak var label2: UILabel!

    @IBOutlet weak var mainStack: UIStackView!

    override var intrinsicContentSize: CGSize {
        get {
            return mainStack.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
        }
    }

    public func setLabel1(_ labelText: String) {
        self.label1.text = labelText
        self.invalidateIntrinsicContentSize()
    }
}