Search code examples
iosobjective-cxcodemkmapviewmkoverlay

Overridden MKMapView drawMapRect method returning errors


I overrode the drawMapRect method in my .m file, but it seems that some lines of code within the rewritten method are giving me errors that I'm not sure how to solve. I made sure that I set to mkmapview delegate to self, all the correct packages were imported. Here is the code for the drawMapRect method,

-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
CGRect rect = [self rectForMapRect:mapRect];
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextFillRect(context, rect);
CGContextRestoreGState(context);

[super drawMapRect:mapRect zoomScale: zoomScale inContext:context];
}

The 2nd line of code is returning an error, "No visible @interface for 'MapViewClass' declares the selector for 'rectForMapRect:'

The last line of code is returning an error. "No visible @interface for 'UIViewController' declares the selector 'drawMapRect: zoomScale: inContext:'

EDIT After looking at Daji's answer, I made the following changes to my code. I made a new class that is a subclass of MKOverlayRenderer, and moved the drawMapRect method to that class. The previous errors I received before are gone now, but the overlay isn't being drawn. Here is additional code from my MapViewClass .m file as well as the MKOverlayRenderer subclass.

#import "MapOverlayRenderer.h"

 @implementation MapOverlayRenderer
-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
CGRect rect = [self rectForMapRect:mapRect];
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextFillRect(context, rect);
CGContextRestoreGState(context);

[super drawMapRect:mapRect zoomScale: zoomScale inContext:context];
}
@end

MapViewClass .m

 - (void)viewDidLoad {
 mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0, 75, 320, 493)];
 mapView.delegate = self;
 mapView.mapType = MKMapTypeStandard;
[self.view addSubview: mapView];
 MKMapRect worldRect = MKMapRectWorld;
 MKCoordinateRegion worldRegion =   MKCoordinateRegionForMapRect(worldRect);

  CLLocationCoordinate2D worldPoints[4];
//Creates corners of the whole map
  worldPoints[0] = CLLocationCoordinate2DMake(worldRegion.center.latitude +    worldRegion.span.latitudeDelta/2.0, worldRegion.center.longitude - worldRegion.span.longitudeDelta/2.0);
        worldPoints[1]= CLLocationCoordinate2DMake(worldRegion.center.latitude - worldRegion.span.latitudeDelta/2.0, worldRegion.center.longitude - worldRegion.span.longitudeDelta/2.0);
        worldPoints[2] = CLLocationCoordinate2DMake(worldRegion.center.latitude + worldRegion.span.latitudeDelta/2.0, worldRegion.center.longitude + worldRegion.span.longitudeDelta/2.0);
        worldPoints[3]= CLLocationCoordinate2DMake(worldRegion.center.latitude - worldRegion.span.latitudeDelta/2.0, worldRegion.center.longitude + worldRegion.span.longitudeDelta/2.0);

        MKPolygon *worldSquare = [MKPolygon polygonWithCoordinates:worldPoints count:4];

        [mapView addOverlay:worldSquare];
}

-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
if([overlay isKindOfClass:[MKPolygon class]]){
    MapOverlayRenderer *polygonView = [[MapOverlayRenderer alloc]initWithOverlay:overlay];

    return polygonView;
}
}

Solution

  • 1.

    you put the code into your ViewController -- the view controller isn't a map view though :)

    Your VC may HAVE a map view but it doesn't ISNT a mapview

    2.

    BUT EVEN MORE CRITICAL:

    the code doesn't belong in a mapView either. you try to use a map overlay. look into using MKOverlayRenderer


    Thats what both error messages say basically:

    1. says your SELF(ViewController) doesn't have a method named rectForMapRect
    2. says your SUPER(UIViewController) doesn't have a method named drawMapRect

    ==> only a MKOverlayRenderer provides them (that is visible from the docs if you search for the two methods)