1
votes

Setting up a map view with annotation of nearby cafes. But when I try to custom the annotations using MKMarkerAnnotationView, nothing shows on the map view. and when I log the marker, the frame is (0 0; 0 0);

I tried pin too, still didn't work.

I set up delegate on storyboard already.

I also debugged the view controller there are marker views but it is not displaying them because the width and height are zero ?

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.cafeMap setShowsUserLocation:YES];

    [self.locationManager requestWhenInUseAuthorization];

    self.cafes = [NSMutableArray array];

    [self fetchData];

    [self.cafeMap registerClass:[MKAnnotationView class] forAnnotationViewWithReuseIdentifier:@"marker"];



}

-(void)fetchData{

    [self.networkManager fetchCafeData:^(NSArray * _Nonnull businesses) {
        for (NSDictionary* cafeInfo in businesses) {
            Cafe *cafe = [[Cafe alloc]initWithCafeInfo:cafeInfo];
            [self.cafes addObject:cafe];
        }

        for (Cafe *cafe in self.cafes) {
            [self.cafeMap addAnnotation:cafe];
        }
        [self.cafeMap showAnnotations:self.cafes animated:YES];
    }];

}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {


    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;
    }
    MKMarkerAnnotationView *marker = [[MKMarkerAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"marker"];
    marker = (MKMarkerAnnotationView*) [mapView dequeueReusableAnnotationViewWithIdentifier:@"marker" forAnnotation:annotation];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];

    marker.rightCalloutAccessoryView = button;

    [marker setEnabled:YES];
    [marker setCanShowCallout:YES];
    NSLog(@"MARKER:%@",marker);
    return marker;


}

This is the output:

MARKER:<MKAnnotationView: 0x7f9fa3f333b0; frame = (0 0; 0 0); layer = <CALayer: 0x60000253d220>>

1

1 Answers

0
votes

Note that your message says that it is a MKAnnotationView. That is because you have registered MKAnnotationView for your identifier rather than MKMarkerAnnotationView. You want:

[self.cafeMap registerClass:[MKMarkerAnnotationView class] forAnnotationViewWithReuseIdentifier:@"marker"];

As an aside, you should be able to simplify viewForAnnotation to:

MKAnnotationView *marker = [mapView dequeueReusableAnnotationViewWithIdentifier:@"marker" forAnnotation:annotation];

Personally, I’d move the configuration of the annotation view into its own subclass:

static NSString * const cafeClusteringIdentifier = @"cafe";

@interface CafeAnnotationView: MKMarkerAnnotationView
@end

@implementation CafeAnnotationView
- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];
        self.rightCalloutAccessoryView = button;
        self.canShowCallout = true;
        self.clusteringIdentifier = cafeClusteringIdentifier;
    }
    return self;
}

- (void)setAnnotation:(id<MKAnnotation>)annotation {
    [super setAnnotation:annotation];
    self.clusteringIdentifier = cafeClusteringIdentifier;
}
@end

By doing this, I avoid bloating my view controller with code for configuring annotation views.

Note, I’m setting the clusteringIdentifier so that you enjoy that behavior of the MKMarkerAnnotationView.

And then I’d register that class for MKMapViewDefaultAnnotationViewReuseIdentifier:

[self.cafeMap registerClass:[CafeAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultAnnotationViewReuseIdentifier];

The benefit of using MKMapViewDefaultAnnotationViewReuseIdentifier is that you don’t have to implement viewForAnnotation at all. Delete your implementation of that method entirely. In iOS 11 and later, you only need to implement viewForAnnotation if you need to do something special like having multiple custom reuse identifiers for multiple types of annotations.

Anyway, that yields:

cafes with callouts