Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify size for iPhone 6/7 customised edge-to-edge image?

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?

iPhone 4,5,6 screen sizes (Image extracted from http://www.iphoneresolution.com)

like image 425
Niklas Berglund Avatar asked Sep 17 '14 13:09

Niklas Berglund


People also ask

What size image is best for iPhone?

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.

What is the diagonal screen size of an iPhone 6?

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.

What is compact and regular in IOS?

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).


2 Answers

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 
like image 145
Jef Avatar answered Sep 24 '22 12:09

Jef


I am using the following trick as some stuff actually works:

  • Asset Catalog for specific devices
  • Specify images for 1x, 2x on the base of 320x640
  • Specify images for 4 2x and 3x on the base of 320x568 (iPhone 5)
  • Create a new Images set for the iPhone 6 specifically (as this is the only device that makes trouble with edge to edge bindings)
  • Only provide 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.

like image 22
Sebastian Flückiger Avatar answered Sep 25 '22 12:09

Sebastian Flückiger