Search code examples
swiftmapkitviewcontrolleruistoryboardseguemapkitannotation

Passing coordinates of selected Annotation to new View Controller Swift 2.0


I am trying to pass the coordinates, title, and subtitle of a selected MKAnnotation from ViewController1 (VC1) to ViewController2 (VC2) when the DetailDisclosure button of rightCalloutAccessoryView is tapped. I have a segue from VC1 to VC2 with the identifier viaSegue. I have a label with identifier viaSegueLabel in VC2 where I want to display the coordinates as a String.

The function that customizes the MKAnnotation's call out so that it displays a DetailDisclosure button in the rightCalloutAccessoryView looks like:

// Customize Annotation Callout
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        // 1
        let identifier = "Capital"

        // 2
        if annotation.isKindOfClass(Capital.self) {
            // 3
            var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

            if annotationView == nil {
                //4
                annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:identifier)
                annotationView!.canShowCallout = true

                // 5
                let btn = UIButton(type: .DetailDisclosure)
                annotationView!.rightCalloutAccessoryView = btn
            } else {
                // 6
                annotationView!.annotation = annotation
            }

            return annotationView
        }

        // 7
        return nil
    }

The function that takes the user from VC1 to VC2 when the DetailDisclosure button is tapped looks like:

// When righCalloutAccessoryView is tapped, segue to newView
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    self.performSegueWithIdentifier("newView", sender: view)
}

And the function I think I need to implement to accomplish this looks like:

// Pass data to newView
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "newView") {
        let destViewController:BusStopSettingsViewController = segue.destinationViewController as! BusStopSettingsViewController
        destViewController.viaSegue = // not sure how to reference selected Annotation here
    }
}

In the last line of prepareForSegue(), I need to reference the MKAnnotation that is currently selected. Is there a method built into Swift that lets me do this, or should I make the Annotation global?


Solution

  • Was able to figure it out in case anyone in the future needs to implement something similar.

    self.performSegueWithIdentifier("newView", sender: view)
    

    programmatically segues your program to the View Controller (VC) that is connected to the VC you are currently in through a segue with identifier "newView". Before it completely segues, the program calls prepareForSegue(). This function is where you will handle sending information to the VC you are segueing to. My issue was, I didn't know exactly what I was sending (in terms of type, variable name, etc.). If you notice, prepareForSegue() and self.performSegueWithIdentifier("newView", sender: view) both have a parameter sender. What you send using performSegueWithIdentifier() will be passed into prepareForSegue() and will be received in your destinationViewController by a variable with the name viaSegue. This isn't a standard name, it's just what I chose to name that variable and if you study the code above, you'll see where it's used and how it works.

    So I wanted to send information about an MKAnnotation I had tapped. So, I needed to send an Object of type MKAnnotationView to my receiving VC "BusStopSettingsViewController" (BSSVC). In BSSVC, I needed a variable called "viaSegue" of type MKAnnotationView. To send BSSVC an object of type MKAnnotationView I needed to do

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if (segue.identifier == "newView") {
            // pass data to next view
            let destViewController:BusStopSettingsViewController = segue.destinationViewController as! BusStopSettingsViewController
            destViewController.viaSegue = sender as! MKAnnotationView
        }
    }
    

    Notice how viaSegue is specified as the variable that'll be receiving this object.

    Hope this helps!