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.

Kraishan
  • 443
  • 5
  • 14
  • 38
  • 1
    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. –  Nov 03 '14 at 12:51
  • 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. –  Nov 03 '14 at 12:57
  • 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) – Kraishan Nov 03 '14 at 14:40
  • Do you have the mapView(mapView:viewForAnnotation:) method implemented? If you do, comment it out and see if the pins show. –  Nov 03 '14 at 14:43
  • If I comment the mapView viewforannotation function it shows the pins. I updated the main post with the current version of viewforannotation. – Kraishan Nov 03 '14 at 14:46

6 Answers6

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
}
  • 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? – Allan Spreys Apr 06 '15 at 06:31
  • 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 view – Andrei Dobrin May 11 '15 at 10:53
  • The blank title fixed it for me. More specifically, I had accidentally deleted the "- (NSString *)title;" declaration from my .h file. – Gazzini Sep 10 '15 at 23:08
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.
Nagarjun
  • 6,557
  • 5
  • 33
  • 51
GOrozco58
  • 1,182
  • 12
  • 10
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.

KAN
  • 61
  • 3
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) 
CamQuest
  • 833
  • 9
  • 16
1

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;
}
Atef
  • 2,872
  • 1
  • 36
  • 32
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)
}
Pigpocket
  • 449
  • 5
  • 24