0
votes

I upgraded a perfectly working 6.1 app to Xcode 5/ios 7 that uses MKMapKit to show some pins on a mapview.

Now the annotation pins dont show up. Ive made sure my mapview delegate is correct and viewForAnnotation is being called. Im also sure its title and subtitle are set, but now the pin just doesnt display. Anyone have any ideas what to look for beyond this?

When it runs, I see my lat/lon, pin title, and subtitle filled in.

Heres my code:

- (MKAnnotationView *) mapView:(MKMapView *) theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
        return nil;
    }

    [self.mapView removeAnnotations:self.mapView.annotations];

    MKPointAnnotation *pt = (MKPointAnnotation *)annotation;

    NSString *PINNAME = pt.title;
    CLLocationDegrees lat = pt.coordinate.latitude;
    CLLocationDegrees lon = pt.coordinate.longitude;
    [Log log:TINFO :@"lat/lon %f - %f", lat, lon];
    [Log log:TINFO :@"pin title userid = %@", pt.title];
    [Log log:TINFO :@"subtitle: %@", pt.subtitle];

    MKPinAnnotationView *pinView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier: PINNAME];

    if(pinView == nil)
    {
        pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:PINNAME];
        pinView.pinColor = MKPinAnnotationColorGreen;
    }
    else
    {
        pinView.annotation = annotation;
    }

    return pinView;
}
2

2 Answers

3
votes

You should remove the call to removeAnnotations from viewForAnnotation, because having it there will remove any annotations that you may have been in the process of displaying on the map. If your intent was to remove old annotations before adding new one, you should do that before you call addAnnotation, not in viewForAnnotation.

Unrelated to your current issue:

  1. And even if you really wanted to remove all the annotations, if it's possible that you might (at some point) have the MKUserLocation on your map, I'd suggest only removing the annotations where the annotation class is not MKUserLocation. I've noticed weird behavior when I accidentally removed the MKUserLocation from the array of annotations.

  2. As an aside, I might suggest using theMapView parameter, rather than self.mapView. You don't want to risk problems stemming from a messed up IBOutlet. No need to reference the self.mapView when theMapView was passed as a parameter.

  3. You're conceivably using a unique identifier for each MKAnnotationView. There's nothing that I see in this code that necessitates that, and you lose much of the efficiencies gained by using dequeued annotations. Use the same identifier string for all annotation views of a particular kind (and you only appear to have one type of annotation).

3
votes
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
    //UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"ttile" message:@"working" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
    //[alert show];
    MKAnnotationView *view = nil;
    if(annotation != mv.userLocation) {
        // if it's NOT the user's current location pin, create the annotation
        Park *parkAnnotation = (Park*)annotation;
        // Look for an existing view to reuse
        view = [mv dequeueReusableAnnotationViewWithIdentifier:@"parkAnnotation"];
        // If an existing view is not found, create a new one
        if(view == nil) {
            view = [[MKPinAnnotationView alloc] initWithAnnotation:(id) parkAnnotation
                                                   reuseIdentifier:@"parkAnnotation"];
        }

        // Now we have a view for the annotation, so let's set some properties
        [(MKPinAnnotationView *)view setPinColor:MKPinAnnotationColorRed];
        [(MKPinAnnotationView *)view setAnimatesDrop:YES];
        [view setCanShowCallout:YES];

        // Now create buttons for the annotation view
        // The 'tag' properties are set so that we can identify which button was tapped later
        UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
        leftButton.tag = 0;
        UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        rightButton.tag = 1;

        // Add buttons to annotation view
        [view setLeftCalloutAccessoryView:leftButton];
        [view setRightCalloutAccessoryView:rightButton];
    }

    // send this annotation view back to MKMapView so it can add it to the pin
    return view;
}