didSelectAnnotationView not called
Asked Answered
S

6

12

I would like to work with an annotation once it's clicked. I've looked it up on the documentation of Apple and I did googled but I can not find why this is any different than how it should be done. Basically; I don't get a println("Pin clicked");

Why not?

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

        return nil
    }

    let reuseId = "test"

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

    }
    else {
        anView.annotation = annotation
    }

    return anView
}
func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!)
{
    println("Pin clicked");
}
func setAnnotationPinOnMap(annotation : NSManagedObject)
{

    var subject: AnyObject? = annotation.valueForKey("subject")
    var desc: AnyObject? = annotation.valueForKey("desc")
    var langitude: AnyObject? = annotation.valueForKey("langitude")
    var longitude: AnyObject? = annotation.valueForKey("longitude")
    println(annotation);
    let pin = MKPointAnnotation()

    let location = CLLocationCoordinate2D(
        latitude: longitude as CLLocationDegrees,
        longitude: langitude as CLLocationDegrees
    )
    println(location.longitude, location.latitude)
    pin.setCoordinate(location)
    pin.title = subject as String!
    pin.subtitle = desc as String!
    println( pin.coordinate.longitude)
    viewForAnnotation(pin);
    mapView.addAnnotation(pin)
}

I have imported map kit and included the map view delegate.

Sector answered 3/11, 2014 at 11:44 Comment(5)
Is the map view's delegate property set? If not, the delegate method won't get called. Also make sure the annotation's title (which is set to subject) is not blank or nil.Gemma
Two unrelated things: 1) When setting location, latitude is set to longitude and longitude is set to langitude which seems backwards. 2) The viewForAnnotation function as written is pointless. It returns a view but the code does nothing with it and it's not named correctly as the map view's delegate method. It must be named func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! and the map view's delegate must be set. You're not supposed to call it directly.Gemma
I did not set the map View's delegate I think. I now set it to : mapView.delegate = self. Now, no pins are shown (formerly pins did show, just not with the click event thrown)Sector
Do you have the mapView(mapView:viewForAnnotation:) method implemented? If you do, comment it out and see if the pins show.Gemma
If I comment the mapView viewforannotation function it shows the pins. I updated the main post with the current version of viewforannotation.Sector
G
15

To answer the original question, didSelectAnnotationView was most likely not getting called because the map view's delegate property was not set. Another common cause is if the annotation's title is blank.

In the updated question, the pins won't show with the way viewForAnnotation is implemented because it creates an MKAnnotationView but doesn't set its image property. The image property of an MKAnnotationView is nil by default so the pins are there but invisible.

If you want to display standard red pins, either:

  • Don't implement the viewForAnnotation delegate method at all and the map view will display red pins by default.
  • Implement the viewForAnnotation delegate method and create an MKPinAnnotationView instead which automatically displays a "pin" image.

So either set the pin's image to some custom image:

anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView.canShowCallout = true
anView.image = UIImage(named:"CustomImage")  // <-- add this line

or create an MKPinAnnotationView instead and optionally set its pinColor:

var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if anView == nil {
    anView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
    anView!.canShowCallout = true
    anView!.animatesDrop = true
    anView!.pinColor = .Purple  // or Red or Green
}
else {
    anView!.annotation = annotation
}
Gemma answered 3/11, 2014 at 14:57 Comment(3)
Hi Anna, thank you very much for such a great answer. My problem (as correctly pointed out by you) was that I didn't set a title for the view. What if I don't want to set a title? Is there any other option?Widgeon
Vlad, did you find an answer to your question? I would also want to make a custom view which has a label in it. The problem is that if I set the title it appears in my View, but also on the right, next to my custom viewSidelight
The blank title fixed it for me. More specifically, I had accidentally deleted the "- (NSString *)title;" declaration from my .h file.Burstone
N
7

In my case the problem was that i was setting the property canShowCallout in YES, so if you set this property in YES

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view

isn't called. when i removed this property the method was called.

annotationView = [[ClusterAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.canShowCallout = YES; //try setting to NO or don't set.
Nordau answered 25/6, 2015 at 22:6 Comment(1)
canShowCallout = false for Swift solved it for me. Thanks :)Beacham
R
3

I wanted to add this as a comment to GOrozco58 answer but do not have enough reputation to comment.

GOrozco58 is right if you have canShowCallout set to YES the didSelectAnnotation will not be called if the title is nil.

If you want didSelectAnnotation to be called and also have canShowCallout set to YES make sure you add a title.

Reformer answered 4/5, 2017 at 15:26 Comment(1)
then lets get you some rep!Arela
B
3

In the latest version of Swift, the method declaration has changed from this:

func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!)

to this:

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) 
Biologist answered 11/12, 2017 at 18:37 Comment(0)
K
2

In my case I was using costume annotation and the didSelectAnnotationView was not being called because of the image property for the custome annotation was empty, so I set it to image and the didSelectAnnotationView started to be called.

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier{
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if (self != nil)
    {
        DoctorCustomeAnnotation *mapItem = (DoctorCustomeAnnotation *)self.annotation;

        // offset the annotation so it won't obscure the actual lat/long location
        self.centerOffset = CGPointMake(100, 100.0);
        self.backgroundColor = [UIColor redColor];
        PAImageView* avatarView = [[PAImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)
                                             backgroundProgressColor:[UIColor whiteColor]
                                                       progressColor:[UIColor colorWithRed:0.092 green:0.383 blue:0.580 alpha:1.000]];
        [self addSubview:avatarView];
        self.image = [UIImage imageNamed:@"placeholder_male"];
        [avatarView setImageURL:@"http://www.straine.com/wp-content/uploads/2015/12/doctor.png"];
    }
    return self;
}
Kafir answered 8/2, 2016 at 17:10 Comment(0)
S
0

Anna's suggestion of the annotation's title not being assigned was the resolution for my problem. It took me a minute to implement this and I did that in gestureRecognizer() function. Here is my example:

    @objc func handleLongPress(_ gestureRecognizer : UIGestureRecognizer) {
    if gestureRecognizer.state != .began { return }
    print("Tap gesture recognized")

    // Create the annotation
    let touchPoint = gestureRecognizer.location(in: mapView)
    let newCoordinate = self.mapView.convert(touchPoint, toCoordinateFrom:self.mapView)
    let annotation = MKPointAnnotation()
    annotation.coordinate = newCoordinate
    annotation.title = "placeholder"

    // Add the annotation
    mapView.addAnnotation(annotation)
}
Skimmia answered 18/11, 2017 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.