MapKit iOS 9 detailCalloutAccessoryView usage

DogCoffee picture DogCoffee · Sep 15, 2015 · Viewed 10.3k times · Source

After watching WWDC video 206 I assumed this would be a trivial task of adding the detail callout view to a mapView annotation view.

So, I assume Im doing something wrong.

With my pin view set up

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
}

I only get this

enter image description here

I know the view is working, because if I try it with the leftCalloutAccessoryView I get enter image description here

I must be missing something. Note, if I just add an image to the detailCalloutAccessoryView like

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

The image is there, size correctly etc

I just cannot figure out how to put in my own custom view.

Thanks

Answer

Klaas picture Klaas · Oct 1, 2015

You have to add some constraints for width and height of your view:

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

Munich 1972

Adding an intrinsicContentSize also works.

I did some testing and found out, that MapKit automagically sets translatesAutoresizingMaskIntoConstraints to false, when you set a view to detailCalloutAccessoryView.

In the WWDC 2015 session "What's New in MapKit" it was told, that "auto layout is supported". I reckon that Apple really means, that you have to use auto layout?!