MapKit iOS 9 detailCalloutAccessoryView的使用

21
观看完WWDC视频206后,我认为将详细信息弹出视图添加到地图标注视图中应该是一项微不足道的任务。
所以,我想我可能做错了什么。
使用我的图钉视图设置。
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")

图片已经在那里,大小也正确。

我只是无法弄清楚如何添加自定义视图。

谢谢

4个回答

22

你需要为你的视图添加一些宽度和高度的约束:

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!
}

慕尼黑1972年

添加intrinsicContentSize也起作用。

我进行了一些测试,并发现当您将视图设置为detailCalloutAccessoryView时,MapKit会自动将translatesAutoresizingMaskIntoConstraints设置为false。

在WWDC 2015会议中“MapKit中的新功能”中提到,“支持自动布局”。 我认为苹果真正意思是您必须使用自动布局?!


5
е¶ВдљХеОїйЩ§detailCalloutAccessoryViewеС®еЫіжЈїеК†зЪДз©Їж†ЉпЉЯ @Klaas - ScottOBot
@ScottOBot 从未尝试过这样做。但是,使用 .Top、.Left、.Bottom 和 .Right 约束条件代替 .Width 和 .Height 可能是可行的吗? - Klaas
@Klaas 如果您正在使用.Top、.Left、.Bottom和.Right约束,那么在创建detailCalloutAccessoryView时,您是否需要引用标题和其他元素?您如何获取它们? - ScottOBot
“支持自动布局”这句话的意思是,我猜苹果真正想表达的是,你必须使用自动布局!-- 典型的苹果 :) - Manav

14

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

enter image description here

在这里,您可以设置大小、约束、添加按钮、图像等-按照您想要的布局。在这种情况下,堆栈视图非常适用。

2.为Maps VC创建一个outlet

像往常一样从自定义视图控件拖动控件并创建 outlet。

@IBOutlet var customDetailView: UIView!

3. 为你的图钉设置detailCalloutAccessoryView

例如:

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

成功

在此输入图片描述


5
这似乎很明显,但我却被困扰了几分钟... 尝试在Storyboard中将UIView拖到空白区域是不起作用的。您需要将其拖到所需使用它的UIViewController上方的顶部栏上。就像黄色圆圈、红色框等旁边一样... - Byron Coetsee
1
@ByronCoetsee,太棒了,可能和答案一样棒。我想知道为什么苹果会做这种复活节彩蛋功能? - Eduardo
太棒了!我在想如何个性化它...放一个按钮并让它执行一些操作,以及带有动态文本的自定义标签...你能给一些想法吗?谢谢! - Cleversou

-1

您可以使用自定义类并覆盖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()
    }
}

-1
使用UIImageView。
view.detailCalloutAccessoryView = UIImageView(image:UIImage(named:"YourImageName")) 

使用图像和图像视图可以让它工作得很好。但是我想使用自定义视图。 - DogCoffee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接