Last active
October 6, 2022 16:35
-
-
Save angelolloqui/3799648 to your computer and use it in GitHub Desktop.
iPhone5 UIImage method swizzling to load -568h images
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UIImage+H568.m | |
// | |
// Created by Angel Garcia on 9/28/12. | |
// Copyright (c) 2012 angelolloqui.com. All rights reserved. | |
// | |
#import <objc/runtime.h> | |
@implementation UIImage (H568) | |
+ (void)load { | |
if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && | |
([UIScreen mainScreen].bounds.size.height > 480.0f)) { | |
//Exchange XIB loading implementation | |
Method m1 = class_getInstanceMethod(NSClassFromString(@"UIImageNibPlaceholder"), @selector(initWithCoder:)); | |
Method m2 = class_getInstanceMethod(self, @selector(initWithCoderH568:)); | |
method_exchangeImplementations(m1, m2); | |
//Exchange imageNamed: implementation | |
method_exchangeImplementations(class_getClassMethod(self, @selector(imageNamed:)), | |
class_getClassMethod(self, @selector(imageNamedH568:))); | |
} | |
} | |
+ (UIImage *)imageNamedH568:(NSString *)imageName { | |
return [UIImage imageNamedH568:[self renameImageNameForH568:imageName]]; | |
} | |
- (id)initWithCoderH568:(NSCoder *)aDecoder { | |
NSString *resourceName = [aDecoder decodeObjectForKey:@"UIResourceName"]; | |
NSString *resourceH568 = [UIImage renameImageNameForH568:resourceName]; | |
//If no 568h version, load as default | |
if ([resourceName isEqualToString:resourceH568]) { | |
return [self initWithCoderH568:aDecoder]; | |
} | |
//If 568h exists, load with [UIImage imageNamed:] | |
else { | |
return [UIImage imageNamedH568:resourceH568]; | |
} | |
} | |
+ (NSString *)renameImageNameForH568:(NSString *)imageName { | |
NSMutableString *imageNameMutable = [imageName mutableCopy]; | |
//Delete png extension | |
NSRange extension = [imageName rangeOfString:@".png" options:NSBackwardsSearch | NSAnchoredSearch]; | |
if (extension.location != NSNotFound) { | |
[imageNameMutable deleteCharactersInRange:extension]; | |
} | |
//Look for @2x to introduce -568h string | |
NSRange retinaAtSymbol = [imageName rangeOfString:@"@2x"]; | |
if (retinaAtSymbol.location != NSNotFound) { | |
[imageNameMutable insertString:@"-568h" atIndex:retinaAtSymbol.location]; | |
} else { | |
[imageNameMutable appendString:@"-568h@2x"]; | |
} | |
//Check if the image exists and load the new 568 if so or the original name if not | |
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageNameMutable ofType:@"png"]; | |
if (imagePath) { | |
//Remove the @2x to load with the correct scale 2.0 | |
[imageNameMutable replaceOccurrencesOfString:@"@2x" withString:@"" options:NSBackwardsSearch range:NSMakeRange(0, [imageNameMutable length])]; | |
return imageNameMutable; | |
} else { | |
return imageName; | |
} | |
} | |
@end |
Answering your questions:
- Apple rejection: There is no reason for that. Method swizzling is allowed and used widely in many places, and
imageNamed
is a public method, so you are not going against any guideline. Besides, I have a few apps using this code without any problem. - XIB files: UPDATE: The new version of the gist includes support for XIB files
I wrote some more info in http://angelolloqui.com/blog/20-iPhone5-568h-image-loading
Hi, 2 things I need to do to make this work flawlessly.
- Change the #import statement to:
#import <objc/runtime.h>
- Wrap the
load
method code in an auto release pool.
It's all perfect, thank you very much
It's really helpful to me, thank you.
I've been using this code (or similar code) for a good 18 months or so.
Quick suggestion - mind submitting this gist to CocoaPods? It'll need to be made into a full-fledged repo before you do so.
+1 for the CocoaPods suggestion!
+1 for the CocoaPods suggestion!
+1 for the CocoaPods suggestion!
+1 for the CocoaPods suggestion!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did someone had a app rejected because of this change in the implementation?
Other question: Does this trick work with UIImages defined in the .xib file? (I did not call the "iimageNamed" method, in fact)