Say I want a bundled image to take up all available screen width in an iPhone app - for example a banner. I'd create my_banner.png
with width 320px
, [email protected]
with width 640px
and [email protected]
for iPhone 6 plus with width 1242px
. But the resolution of iPhone 6 is 750×1334
pixels. Still it shares the @2x
suffix with iPhone 4 and 5 that have 640px
width.
What's the recommended way or a good way to specify an image file that has been optimised for the 750px
width of iPhone 6? Seems like it cannot be done in an asset catalog
? Should it be done programatically? Is there some other suffix that can be used for iPhone 6?
(Image extracted from http://www.iphoneresolution.com)
Your iPhone uses a ratio of 3:4 by default, which means that if you wanted to print a 3 x 4 photo or a 6 x 8 photo, you could do it without any cropping at all.
The Apple iPhone 6 (8th Gen) has height of 5.44” (138.1 mm), width of 2.64” (67 mm), depth of . 27” (6.9 mm), and weighs 4.6 oz (129 g). The screen size is 4.7” (120 mm) diagonal with a resolution of 1334 x 750 px at 326 ppi.
The Compact Size Class refers to a constrained space. It is denoted in Xcode as wC (Compact width) and hC (Compact height). The Regular Size Class refers to a non-constrained space. It is denoted in Xcode as wR (Regular width) and hR (Regular height).
It seems to me that a lot of these answers want to address how to constrain the imageView, where I think you are concerned with loading the correct media file? I would come up with my own future extensible solution, something like this:
"UIImage+DeviceSpecificMedia.h" - (a category on UIImage)
Interface:
#import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger, thisDeviceClass) { thisDeviceClass_iPhone, thisDeviceClass_iPhoneRetina, thisDeviceClass_iPhone5, thisDeviceClass_iPhone6, thisDeviceClass_iPhone6plus, // we can add new devices when we become aware of them thisDeviceClass_iPad, thisDeviceClass_iPadRetina, thisDeviceClass_unknown }; thisDeviceClass currentDeviceClass(); @interface UIImage (DeviceSpecificMedia) + (instancetype )imageForDeviceWithName:(NSString *)fileName; @end
Implementation:
#import "UIImage+DeviceSpecificMedia.h" thisDeviceClass currentDeviceClass() { CGFloat greaterPixelDimension = (CGFloat) fmaxf(((float)[[UIScreen mainScreen]bounds].size.height), ((float)[[UIScreen mainScreen]bounds].size.width)); switch ((NSInteger)greaterPixelDimension) { case 480: return (( [[UIScreen mainScreen]scale] > 1.0) ? thisDeviceClass_iPhoneRetina : thisDeviceClass_iPhone ); break; case 568: return thisDeviceClass_iPhone5; break; case 667: return thisDeviceClass_iPhone6; break; case 736: return thisDeviceClass_iPhone6plus; break; case 1024: return (( [[UIScreen mainScreen]scale] > 1.0) ? thisDeviceClass_iPadRetina : thisDeviceClass_iPad ); break; default: return thisDeviceClass_unknown; break; } } @implementation UIImage (deviceSpecificMedia) + (NSString *)magicSuffixForDevice { switch (currentDeviceClass()) { case thisDeviceClass_iPhone: return @""; break; case thisDeviceClass_iPhoneRetina: return @"@2x"; break; case thisDeviceClass_iPhone5: return @"-568h@2x"; break; case thisDeviceClass_iPhone6: return @"-667h@2x"; //or some other arbitrary string.. break; case thisDeviceClass_iPhone6plus: return @"-736h@3x"; break; case thisDeviceClass_iPad: return @"~ipad"; break; case thisDeviceClass_iPadRetina: return @"~ipad@2x"; break; case thisDeviceClass_unknown: default: return @""; break; } } + (instancetype )imageForDeviceWithName:(NSString *)fileName { UIImage *result = nil; NSString *nameWithSuffix = [fileName stringByAppendingString:[UIImage magicSuffixForDevice]]; result = [UIImage imageNamed:nameWithSuffix]; if (!result) { result = [UIImage imageNamed:fileName]; } return result; } @end
I am using the following trick as some stuff actually works:
1x
, 2x
on the base of 320x6404 2x
and 3x
on the base of 320x568 (iPhone 5)2x
image for iPhone 6 in full resolution (750x1334)Declare a constant
#define IS_IPHONE_6 [[UIScreen mainScreen]nativeBounds].size.width == 750.0 ? true : false
and use it like this:
UIImage *image = [UIImage imageNamed:@"Default_Image_Name"]; if(IS_IPHONE_^) { image = [UIImage imageNamed:@"Iphone6_Image_Name"]; }
this might be not the most beautiful solution, but it works, at least as long as apple does not provide a better API for edge to edge bindings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With