2

I am trying to display some annotations on a map. I want to use the MKMapView class because of the way it handles annotations, it's great for me. But I have my custom map system which works with its own view. I have tried to implement method swizzling as suggested in this answer: https://stackoverflow.com/a/10702022/1152596 , but I had no luck. The tiles are not being displayed, which is ok, but the background is not transparent, it has a gray-like color. See screenshot below:

Screenshot

The black path is my annotation. Behind is the view with my own map I don't get to see. I'm sure it's behind, if I don't add MKMapView I can see it.

I know what I'm trying here is very hacky, but no alternative came to my mind.

The code for the swizzling from the linked answer is:

I define:

// Import runtime.h to unleash the power of objective C 
#import <objc/runtime.h>

// this will hold the old drawLayer:inContext: implementation
static void (*_origDrawLayerInContext)(id, SEL, CALayer*, CGContextRef);

// this will override the drawLayer:inContext: method
static void OverrideDrawLayerInContext(UIView *self, SEL _cmd, CALayer *layer, CGContextRef context)
{
    // uncommenting this next line will still perform the old behavior
    //_origDrawLayerInContext(self, _cmd, layer, context);

    // change colors if needed so that you don't have a black background
    layer.backgroundColor = RGB(35, 160, 211).CGColor;

    CGContextSetRGBFillColor(context, 35/255.0f, 160/255.0f, 211/255.0f, 1.0f);
    CGContextFillRect(context, layer.bounds);
}

In my viewDidLoad method:

UIView* scrollview = [[[[mapView subviews] objectAtIndex:0] subviews] objectAtIndex:0];
UIView* mkTiles = [[scrollview subviews] objectAtIndex:0]; // <- MKMapTileView instance

// Retrieve original method object
Method  origMethod = class_getInstanceMethod([mkTiles class], 
                                             @selector(drawLayer:inContext:));

// from this method, retrieve its implementation (actual work done)
_origDrawLayerInContext = (void *)method_getImplementation(origMethod);

// override this method with the one you created    
if(!class_addMethod([mkTiles class],
                    @selector(drawLayer:inContext:), 
                    (IMP)OverrideDrawLayerInContext,
                    method_getTypeEncoding(origMethod)))
{
    method_setImplementation(origMethod, (IMP)OverrideDrawLayerInContext);
}
Community
  • 1
  • 1
The dude
  • 7,896
  • 1
  • 25
  • 50
  • Is there no way your tile system could be used as a source for MKMapView? If it could then you'd wouldn't have to keep two map objects in sync – Craig Nov 08 '13 at 19:40

0 Answers0