heliang219
11/27/2019 - 9:32 AM

We swizzle in a fix for the iOS 13 RouteMe/Mapbox (legacy) tiling bug via a category on UIImage.

We swizzle in a fix for the iOS 13 RouteMe/Mapbox (legacy) tiling bug via a category on UIImage.

#import "UIImage+FixIOS13Bug.h"
#import <objc/runtime.h>


/**
 * Fix UIImage -drawRect: bug in iOS 13 that impacts RouteMe library tiling.
 *
 * SEE: https://forums.developer.apple.com/thread/120526
 */
@implementation UIImage (FixIOS13Bug)

+ (void)load
{
    // https://nshipster.com/method-swizzling/
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        if (@available(iOS 13.0, *)) {
            NSLog(@"Applying iOS 13 fix for UIImage -drawRect:");
            Class clazz = [self class];
            
            SEL originalSelector = @selector(drawInRect:);
            SEL swizzledSelector = @selector(s6_drawInRect:);
            
            Method originalMethod = class_getInstanceMethod(clazz, originalSelector);
            Method swizzledMethod = class_getInstanceMethod(clazz, swizzledSelector);
            
            BOOL methodAdded = class_addMethod(clazz,
                                               originalSelector,
                                               method_getImplementation(swizzledMethod),
                                               method_getTypeEncoding(swizzledMethod));
            
            if (methodAdded) {
                class_replaceMethod(clazz,
                                    swizzledSelector,
                                    method_getImplementation(originalMethod),
                                    method_getTypeEncoding(originalMethod));
            }
            else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }
    });
}


- (void)s6_drawInRect:(CGRect)rect
{
    // This is the actual fix.
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);
    UIImage* flipped = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGContextDrawImage(ctx, rect, flipped.CGImage);
}

@end