35

With the retina we make images with the @2x in the name. I see where the default image has to be default-568h@2x but this does not seem to be the case for other images. Like if my background is bg.png and bg@2x.png I tried using bg-568h@2x.png but that does not work. Can somebody tell me what the images need to be named to support the iPhone 5?

mmoore410
  • 417
  • 1
  • 5
  • 12
  • 1
    As answered there is no suffix that automatically works. There is an alternative solution explained at http://angelolloqui.com/blog/20-iPhone5-568h-image-loading – Angel G. Olloqui Sep 30 '12 at 10:48
  • If you are looking for something similar to `~iPad` or `~iPhone` (like `~586h`) there isn't anything build in like that. But you can easily add it yourself by expanding UIImage class. Have a look at [this source snippet (UIImage+Retina4)](http://www.sourcedrop.net/FY53a14b0127f) for information about how to achieve. Just add this UIImage category and there will be support for ~568h@2x files. – miho Sep 23 '12 at 15:50

6 Answers6

56

No special suffix for iPhone 5 (4'' display), just the specific Default-568h@2x.png file.

Here's a macro to handle it:

// iPhone 5 support
#define ASSET_BY_SCREEN_HEIGHT(regular, longScreen) (([[UIScreen mainScreen] bounds].size.height <= 480.0) ? regular : longScreen)

Usage: (assets names - image.png, image@2x.png, image-568h@2x.png)

myImage = [UIImage imageNamed:ASSET_BY_SCREEN_HEIGHT(@"image",@"image-568h")];
Avishay Cohen
  • 2,418
  • 1
  • 22
  • 40
  • 9
    Great solution!! I would suggest just a little change in the macro in order to simplify coding: `#define ASSET_BY_SCREEN_HEIGHT(regular) (([[UIScreen mainScreen] bounds].size.height <= 480.0) ? regular : [regular stringByAppendingString:@"-568h"])` – Alexandre OS Mar 26 '13 at 22:28
  • Very clean solution! Apple should have made this available automatically with the imageNamed: API – DZenBot Jun 13 '13 at 22:43
  • @user1470914 Either would work, I've added it to 'macros.h' file and imported it in the .pch so macro is available from all files – Avishay Cohen Feb 11 '14 at 13:07
  • No longer works consistently in iOS 8 because the UIScreen mainScreen bounds are rotated if the device is in landscape. If your app doesn't rotate then it should be fine – Danny Sep 12 '14 at 19:51
25

There is no specific image name. Having the Default-568h@2x will launch that image on an iPhone 5 or iPod Touch 5G and will enable the non-letterbox mode. After that, you need to design your views to be flexible. There is no special "image name" or anything for the new size.

For your background, for example, you should probably be using an image that is capable of stretching or tiling and have it configured properly before setting it.

Jason Coco
  • 77,985
  • 20
  • 184
  • 180
1

iPhone 5 does not have a different pixel density, it's the same retina display PPI as the iPhone 4/4S, it's just a different screen size. The @2x images will be used on iPhone 5 as well as 4/4S.

Wasim
  • 4,953
  • 10
  • 52
  • 87
1

To complete Jason's answser, I would propose: What about overriding the UIImage's imageNamed: method to have it happen the "-568" suffix to the name of your image? Or add a new method called resolutionAdaptedImageNamed: to the UIImage maybe using a category.

If I have a bit of time in the next days, I will try to post the code for that.

Caution: will not work for images in the Nib files.

MonsieurDart
  • 6,005
  • 2
  • 43
  • 45
1

If you are using Xcode 5, you can use asset catalog (see usage there Apple's documentation)

Once your asset catalog is created [ UIImage imagedNamed: @"your_image_set" ] will pull right image based on device.

hsarret
  • 446
  • 1
  • 3
  • 10
0

You can also make category for this just make category as below .

UIImage+Retina4.h
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
 @interface UIImage (Retina4)
 @end

UIImage+Retina4.m
#import "UIImage+Retina4.h"
static Method origImageNamedMethod = nil;
@implementation UIImage (Retina4)

+ (void)initialize {
origImageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
method_exchangeImplementations(origImageNamedMethod,
                               class_getClassMethod(self, @selector(retina4ImageNamed:)));
}
+ (UIImage *)retina4ImageNamed:(NSString *)imageName {
// NSLog(@"Loading image named => %@", imageName);
NSMutableString *imageNameMutable = [imageName mutableCopy];
NSRange retinaAtSymbol = [imageName rangeOfString:@"@"];
if (retinaAtSymbol.location != NSNotFound) {
    [imageNameMutable insertString:@"-568h" atIndex:retinaAtSymbol.location];
} else {
    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) {
        NSRange dot = [imageName rangeOfString:@"."];
        if (dot.location != NSNotFound) {
            [imageNameMutable insertString:@"-568h@2x" atIndex:dot.location];
        } else {
            [imageNameMutable appendString:@"-568h@2x"];
        }
    }
}

NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageNameMutable ofType:@"png"];
if (imagePath) {
    return [UIImage retina4ImageNamed:imageNameMutable];
} else {
    return [UIImage retina4ImageNamed:imageName];
}
return nil;
}

@end

And you can directly check using import this category as below where you wont to check 568 or normal image

imgvBackground.image=[UIImage imageNamed:@"bkground_bg"];//image name without extantion
sinh99
  • 3,909
  • 32
  • 32