Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MapKit iOS 9 detailCalloutAccessoryView usage

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

like image 752
DogCoffee Avatar asked Sep 15 '15 08:09

DogCoffee


2 Answers

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

like image 155
Klaas Avatar answered Nov 11 '22 23:11

Klaas


1. Create a UIView and add it to yours maps VC in the Storyboard

enter image description here

Here you can set the size, constraints, add buttons, images, etc - layout how you want. Stack views work perfect in this instance.

2. Create and outlet to your Maps VC

Control drag as per usual, from your custom view.

@IBOutlet var customDetailView: UIView!

3. Set the detailCalloutAccessoryView for your pin

For example

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

Success

enter image description here

like image 34
DogCoffee Avatar answered Nov 11 '22 23:11

DogCoffee