Home / IOS Development / ios – Obj-C – All custom MKMapView annotations do not always appear on MapView?

ios – Obj-C – All custom MKMapView annotations do not always appear on MapView?



As Ramis said, the problem is that you insert displayPriority before you even instantiate pulsingView. Thus it is MKAnnotationView you later instantiate never got his displayPriority set.

That said, I would suggest a slightly different implementation. In particular, I want to move the comment view configuration to its own subclass, instead of messing up the view controller with this type of code:

@interface MeetUpAnnotationView: MKAnnotationView
@end

@implementation MeetUpAnnotationView

- (instancetype)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if (self) {
        self.displayPriority = MKFeatureDisplayPriorityRequired;
        self.canShowCallout = YES;
        self.image = [UIImage imageNamed:@"meetupbeacon.png"];
    }
    return self;
}

- (void)setAnnotation:(id)annotation {
    [super setAnnotation:annotation];
    self.displayPriority = MKFeatureDisplayPriorityRequired;
}

@end

Then, if you̵

7;re targeting iOS 11 or later, your viewer viewDidLoad should register that subclass.

Now, if this is the only comment view you see in iOS 11, you do not need one viewForAnnotation at all and can only register standard annotation:

[self.mapView registerClass:[MeetUpAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultAnnotationViewReuseIdentifier];

And after registering the brand class, you’re done. no viewForAnnotation is necessary or desired.


The only time you need to implement viewForAnnotation in iOS 11 and later is if you have several custom annotation view types on your map. In that case, register them:

[self.mapView registerClass:[MeetUpAnnotationView class] forAnnotationViewWithReuseIdentifier:meetupIdentifier];
[self.mapView registerClass:[SomeOtherAnnotationView class] forAnnotationViewWithReuseIdentifier:someOtherIdentifier];

And then use dequeueReusableAnnotationViewWithIdentifier:forAnnotation: in your viewForAnnotation:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
    if ([annotation isKindOfClass:[MeetupAnn class]]) {
        return [mapView dequeueReusableAnnotationViewWithIdentifier:meetupIdentifier forAnnotation:annotation];
    }

    if ([annotation isKindOfClass:[SomeOtherAnnotation class]]) {
        return [mapView dequeueReusableAnnotationViewWithIdentifier:someOtherIdentifier forAnnotation:annotation];
    }

    ...

    return nil;
}

As you can see, in iOS 11 (especially when you only have one comment view type), the code is greatly simplified.

However, if you need to support older versions of iOS, you can not register the identifier and you must use the older one dequeueReusableAnnotationViewWithIdentifier:, but I still want to let the subclass comment field take care of configuring itself. But a more subtle problem in your code is that you do not insert annotation in a else clause, so be sure to do so, e.g.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
    if ([annotation isKindOfClass:[MeetupAnn class]]) {
        MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:meetupIdentifier];
        if (!annotationView) {
            annotationView = [[MeetUpAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:meetupIdentifier];
        } else {
            annotationView.annotation = annotation;
        }
        return annotationView;
    }

    return nil;
}


Source link