Search code examples
swiftmkpointannotation

Add button to MKPointAnnotation


Having a problem when i try to add a button in a annotation.

Before i've asked this question i've searched for answers on the following pages: How to add a button to the MKPointAnnotation? , Adding a button to MKPointAnnotation? etc. But all couldn't help me.

This what is tried to do:

var annotation1 = MKPointAnnotation()
annotation1.setCoordinate(locationKamer1)
annotation1.title = "Title1"
annotation1.subtitle = "Subtitle1"
// here i want to add a button which has a segue to another page.
mapView.addAnnotation(annotation1)

Don't know if what i try to do isn't working. I'm experimenting with swift for the first time.

Hope someone can help me :)

Thanks in advance!


Solution

  • That answer in your first link is basically right, though it needs to be updated for Swift 2.

    Bottom line, in answer to your question, you don't add the button when you create the annotation. You create the button when you create its annotation view in viewForAnnotation.

    So, you should:

    1. Set the view controller to be the delegate of the map view.

    2. Make the view controller conform to the map view delegate protocol, e.g.:

      class ViewController: UIViewController, MKMapViewDelegate { ... }
      
    3. Add a segue from the view controller (not the button) to the next scene by control dragging from the view controller icon above the scene with the map view to the next scene:

      enter image description here

      Then select that segue and then give it a storyboard identifier ("NextScene" in my example, though you should use a more descriptive name):

      enter image description here

    4. Implement viewForAnnotation to add button as right accessory.

      func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
          var view = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier)
          if view == nil {
              view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
              view?.canShowCallout = true
              view?.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure)
          } else {
              view?.annotation = annotation 
          }
          return view
      }
      
    5. Implement calloutAccessoryControlTapped which (a) captures which annotation was tapped; and (b) initiates the segue:

      var selectedAnnotation: MKPointAnnotation!
      
      func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
          if control == view.rightCalloutAccessoryView {
              selectedAnnotation = view.annotation as? MKPointAnnotation
              performSegueWithIdentifier("NextScene", sender: self)
          }
      }
      
    6. Implement a prepareForSegue that will pass the necessary information (presumably you want to pass the annotation and therefore have a annotation property in that second view controller).

      override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
          if let destination = segue.destinationViewController as? SecondViewController {
              destination.annotation = selectedAnnotation
          }
      }
      
    7. Now you can create your annotation like you were before:

      let annotation = MKPointAnnotation()
      annotation.coordinate = coordinate
      annotation.title = "Title1"
      annotation.subtitle = "Subtitle1"
      mapView.addAnnotation(annotation)