Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
iPhone5 UIImage method swizzling to load -568h images
//
// 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
Owner

angelolloqui commented Sep 28, 2012

A quick explanation of the above code can be found at http://angelolloqui.com/blog/20-iPhone5-image-loading

rt-Xor commented Dec 13, 2012

HI, Thanks for this little code it is so helpful for porting my app for iPhone5.
I have one query that , will apple approve this thing as we are making a category but we are also replacing their method of imageNamed with your Method . Basically we are overriding laod method of NSObject, i saw one post regarding category in which it was mentioned that we should avoid overriding method of NSObject while making any category. Please clear my doubts.

yes, my concern too. Apple could possible reject it.

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)

Owner

angelolloqui commented Jun 4, 2013

Answering your questions:

  1. 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.
  2. 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.

  1. Change the #import statement to: #import <objc/runtime.h>
  2. Wrap the load method code in an auto release pool.
Owner

angelolloqui commented Jul 25, 2013

I updated the Gist with changes to make XIB images also -568h compatible. Thanks to Alex Zak (@A-Zak) for pointing out a solution and specially to Artem Shimanski (@mrdepth) for inventing this trick for his own utility.

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