Dim
Dim

Reputation: 532

Swift Annotation click button

I have a mapView with a custom annotation. I also added a button to this but is there a way to see on which annotation the button was pressed?

Here is the code:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    if !(annotation is CustomPointAnnotation) {
        return nil
    }

    let reuseId = "test"

    var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
    if anView == nil {
        anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        anView!.canShowCallout = true
        anView!.enabled = true


        anView?.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure) 

        let imageview_left = UIImageView(frame: CGRectMake(0, 0, 20, 20))
        imageview_left.image = UIImage(named: "left.png")
        anView?.leftCalloutAccessoryView = imageview_left

        let imageview_right = UIImageView(frame: CGRectMake(0, 0, 8, 13))
        imageview_right.image = UIImage(named: "right.png")
        anView!.rightCalloutAccessoryView = imageview_right

    }
    else {
        anView!.annotation = annotation
    }


    let subtitleView = UILabel()
    subtitleView.font = UIFont(name: "GillSans-Light", size: 14)
    subtitleView.numberOfLines = 1
    subtitleView.text = annotation.subtitle!
    anView!.detailCalloutAccessoryView = subtitleView


    let cpa = annotation as! CustomPointAnnotation
    anView!.image = UIImage(named:cpa.imageName)

    return anView
}

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

    if control == view.rightCalloutAccessoryView {
        print("Pressed!")

    }
    print("Click")
}

When I click on the rightCalloutAccessoryView nothing happens. When I click on the title or subtitle annotation nothing happens too. What I made wrong?

Upvotes: 1

Views: 4442

Answers (2)

Code Different
Code Different

Reputation: 93191

The way you do that is to add a target to the button:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    // ...

    if anView == nil {
        // ... 
        let button = MyButton(type: .DetailDisclosure)
        button.addTarget(self, action: #selector(ViewController.showAnnotationDisclosure(_:)), forControlEvents: .TouchUpInside)

        anView!.rightCalloutAccessoryView = button
    }

    return anView
}

func showAnnotationDisclosure(sender: AnyObject) {
    print("Disclosure button clicked")
}

Now if you want to know what annotation was clicked, you have to subclass UIButton:

class MyButton : UIButton {
    var annotation: CustomPointAnnotation? = nil
}

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    // ...
    if anView == nil {
        // ...
        let button = MyButton(type: .DetailDisclosure)
        button.addTarget(self, action: #selector(ViewController.showAnnotationDisclosure(_:)), forControlEvents: .TouchUpInside)

        anView!.rightCalloutAccessoryView = button
    }

    if let button = anView!.rightCalloutAccessoryView as? MyButton {
        button.annotation = annotation
    }

    return anView
}

func showAnnotationDisclosure(sender: MyButton) {
    print("Disclosure button clicked")
    print(sender.annotation?.title)
}

Upvotes: 3

herby
herby

Reputation: 389

According to the apple docs the delegate methods for pressing leftCalloutAccessoryView or rightCalloutAccessoryView will only be called if they are descendants of UIControl

So either do that or handle the gestures yourself by adding e.g instances of UITapGestureRecognizer to the appropriate views. Remember that if those are instances of UIImageView you also have to set instance.userInteractionEnabled = true

docs

Upvotes: 0

Related Questions