MapKit iOS 9 detailCalloutAccessoryView 使用

Posted

技术标签:

【中文标题】MapKit iOS 9 detailCalloutAccessoryView 使用【英文标题】:MapKit iOS 9 detailCalloutAccessoryView usage 【发布时间】:2015-12-11 09:55:58 【问题描述】:

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

所以,我认为我做错了什么。

设置我的 pin 视图

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")

图像在那里,大小正确等

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

谢谢

【问题讨论】:

【参考方案1】:

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

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 会议"What's New in MapKit" 中被告知,“支持自动布局”。我认为 Apple 的真正意思是,您必须使用自动布局?!

【讨论】:

如何去掉detailCalloutAccessoryView 周围添加的间距? @克拉斯 @ScottOBot 从未尝试过。但是可以通过使用 .Top、.Left、.Bottom 和 .Right 约束而不是 .Width 和 .Height 来实现? @Klaas 如果您使用 .Top、.Left、.Bottom 和 .Right 约束,您不需要在标注中引用标题和其他元素吗?在创建 detailCalloutAccessoryView 时如何获得它? ““支持自动布局”。我认为苹果的真正意思是,你必须使用自动布局! -- 典型的:)【参考方案2】:

1.创建一个 UIView 并将其添加到 Storyboard 中的地图 VC

您可以在此处设置大小、约束、添加按钮、图像等 - 以您想要的方式布局。堆栈视图在这种情况下完美运行。

2。创建并输出到您的 Maps VC

从您的自定义视图中照常控制拖动。

@IBOutlet var customDetailView: UIView!

3.为您的 pin 设置 detailCalloutAccessoryView

例如

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

成功

【讨论】:

这可能看起来很明显,但它让我陷入了几分钟......试图将 UIView 拖到情节提要的开放空间中是行不通的。您需要将它拖到您希望使用它的 UIViewController 上方的顶部栏上。就像在那个黄色圆圈、红色框等旁边... @ByronCoetsee,这很好,可能和答案一样好。我想知道为什么苹果会做这种复活节彩蛋功能? 太棒了!我想知道如何个性化它...放置一个按钮并使其执行某些操作,以及带有动态文本的自定义标签...您能给出一些想法吗?谢谢!【参考方案3】:

使用 UIImageView

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

【讨论】:

让它与图像和图像视图一起工作很好。我想使用自定义视图。【参考方案4】:

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

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

这是一个使用堆栈视图内的两个标签的示例。 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()
    

【讨论】:

以上是关于MapKit iOS 9 detailCalloutAccessoryView 使用的主要内容,如果未能解决你的问题,请参考以下文章

IOS-MapKit

iOS 5 MapKit,MKPlacemark,在 iOS 5 上运行 iOS 4.3 应用程序

iOS MapKit,细节较少

iOS 6 上的 MapKit 崩溃

IOS/MapKit:通过单击 MKPlacemark 启动本机地图应用程序

iOS 7 中的 Mapkit 路由