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

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


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:

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


Auto Layout is supposed to help with this situation..

Now tell me @Nicklas Berglund what would you do if the device rotates? Lets say you are in landscape mode now.. How would you fill the Horizontal space which is not in the image assets any more?

Just food for thoughts.. Auto Layout supposed to take care of your screen no matter which orientation, or which device you are running your app on..

Maybe Apple should start targeting device orientations in image assets in future?

Lets go back to your question.. The solution is to replace your @2x images with 750px wide images and then have Auto Layout do its job. Oh yea, this is the tricky part..

If you just add constraints to fit it, it will squeeze it horizontally when displayed in 4" screen, but you can use multipliers to scale the image appropriately. Here's how you can do it:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageFooterView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageFooterView)]];[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageFooterView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageFooterView)]];float aspectRatio = imageFooterView.frame.size.height/imageFooterView.frame.size.width;[imageFooterView addConstraint:[NSLayoutConstraint constraintWithItem:imageFooterView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:imageFooterView attribute:NSLayoutAttributeWidth multiplier:aspectRatio constant:0.0f]];