0

I am trying to present another view controller once the right callout button is pressed but it must go to the correct indexPath, similar to how this happens in a table view. this is where I am up to:

I have created a custom annotation like so:

class annotationCustom: NSObject, MKAnnotation {

    var coordinate : CLLocationCoordinate2D
    var title : NSString!
    var subtitle : NSString!
    var isUserAnnotation : Bool
    var dataImage = [NSData]()

    init(coordinate: CLLocationCoordinate2D, title: NSString!, subtitle: NSString!){

        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
        self.isUserAnnotation = false
    }
}

and then set the viewForAnnotation like so:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        var dqPin = "pin"

        var view = mapView.dequeueReusableAnnotationViewWithIdentifier(dqPin) as? MKPinAnnotationView

                view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: dqPin)
                view!.canShowCallout = true

                    var arrowBut = UIImage(named: "arrow")
                    var arrowButton = UIButton()
                    arrowButton.setImage(arrowBut, forState: UIControlState.Normal)
                    arrowButton.tintColor = UIColor.blackColor()
                    arrowButton.frame = CGRectMake(0, 0, 30, 30)
                    view!.rightCalloutAccessoryView = arrowButton
                   }
             return view
             }

Now I know I have to use the function:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
            func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {

        if control == view.rightCalloutAccessoryView {

        let sb = UIStoryboard(name: "Main", bundle: nil)
        let userProfileVC = sb.instantiateViewControllerWithIdentifier("usersProfileVC") as UsersProfilesViewController

                userProfileVC.profileName = annotationCustom.title // error: 'annotationCustom.Type' does not have a member named 'title'

        performSegueWithIdentifier("goToUserFromMap", sender: self)
    }

}

}

Can somebody fill in the gaps or help me out please.

Thanks

Henry Brown
  • 2,219
  • 8
  • 31
  • 48
  • What exactly is not clear? If you're wondering how you know which annotation the method is being called, it's `view.annotation` (a reference to the `annotationCustom` object that you added). –  Mar 11 '15 at 00:48
  • What i'm not sure how to do is once the right callout accessory is tapped, how do i segue to the next view controller from the indexPath of that particular annotation. I don't know how to write/do it? – Henry Brown Mar 11 '15 at 10:27
  • Don't think of or use "indexPath" with annotations. They don't have a specific order to the map view like rows do to a table view. The calloutAccessoryControlTapped method gives a direct reference to the annotation in question that you access using `view.annotation`. **Regarding how to do the segue:** see http://stackoverflow.com/questions/14805954/mkannotationview-push-to-view-controller-when-detaildesclosure-button-is-clicked. It's in Objective-C but it should not be difficult to convert to Swift. Also see http://stackoverflow.com/questions/26536080/swift-programmatically-set-segues. –  Mar 11 '15 at 11:12
  • I understand that bit, but how do i write it e.g. for a table view you would write something like this: `var secondVC : UsersProfilesViewController = segue.destinationViewController as UsersProfilesViewController secondScene.profileName = self.profile.names[indexPath.row]` using the `indexPath` to reference to the selected row. I don't know how to reference to the selected annotation to be able to pass information across. – Henry Brown Mar 11 '15 at 11:29
  • Add whatever data is needed per annotation (eg. profileName:String!) to your custom annotation class (annotationCustom). When _creating_ the annotations, set the profileName (copy it from the profile.names[x]). Then in the delegate method, the view.annotation object will have the data right with it (you won't need to refer back to the source data). –  Mar 11 '15 at 11:36
  • I have edited my code slightly although I am getting an error, how do I call the rightCalOutView? – Henry Brown Mar 11 '15 at 12:15

1 Answers1

0

Instead of:

if control == annotationView.rightCalloutAccessoryView {

it should be:

if control == view.rightCalloutAccessoryView {

view is the internal, private name of the parameter and annotationView is the external name visible to the caller.

However, in this case, you don't really need to check control in the first place since your callouts have only a single control (rightCalloutAccessoryView). They don't have a leftCalloutAccessoryView so there's only one control the user could tap.

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {

    println("disclosure pressed on: \(view.annotation.title)")

}


By the way, is the code shown in viewForAnnotation the actual code? Because it looks like the result of the dequeueReusableAnnotationViewWithIdentifier is ignored and there is a mysterious extra closing } before the return view.


Here:
userProfileVC.profileName = annotationCustom.title

annotationCustom is the name of your class -- not the instance of it (also, convention is to start class names with a capital letter). view.annotation is the instance here. Cast it as annotationCustom to access any custom properties (though title isn't custom):

if let ac = view.annotation as? annotationCustom {
    userProfileVC.profileName = ac.title
}
  • No it wasn't the full code as i made it smaller so it was easier to understand, I have edited my code again as the function is running now I just don't know how to pass over information in the `calloutAccessoryControlTapped`. I can't work it out...? – Henry Brown Mar 11 '15 at 13:18