Images for iphone 5 retina display
Asked Answered
Z

5

19

iPhone 5 released, with new screen size and resolution.

When we used images for iPhone 4 (retina), we just added "@2x" to image name. Can anybody tell me, is it possible to add different images (backgrounds, buttons, etc), for new iPhone screen?

And the second question: can I have in my app separate XIB files: for iPhone old, iPhone new (like for iPhone and iPad)?

Thank you!

Zenas answered 21/9, 2012 at 14:21 Comment(1)
You should separate different questions into different questions.Nonstandard
F
50

Here's an except from my blog about this subject:

[UIImage imageNamed:] automatically loads @2x versions of images when running on a retina device. Unfortunately, imageNamed: will NOT automatically load -568h@2x versions of images when running on an iPhone 5.

Sometimes this doesn't matter, for example icons and non-full screen graphics are probably the same on iPhone 4 & 5. However, if you have full-screen background images, or full-width / height background images for toolbars etc you will have problems. Your 480-high images will most likely get stretched (and will probably look horrid as a result).

You can manually check the screen size and load the right image like this:

UIImage* myImage;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) {
   myImage = [UIImage imageNamed:@"myImage-568h.png"];
} else {
   myImage = [UIImage imageNamed:@"myImage.png"];
}

There's a way of altering UIImage imageNamed so it does automatically load the right image. See link below for details.

More at: http://pervasivecode.blogspot.co.uk/2012/09/making-apps-work-on-iphone-5-screen-size.html

EDIT: @Sound Blaster & @GrizzlyNetch are right, in code you should use imageNamed:@"myImage-568h.png"] but the actual file name should be [email protected]. If you don't do this, then the scale is incorrect, just like they said.

Finnie answered 21/9, 2012 at 14:28 Comment(6)
I think, right image name is 'myImage-568h.png' - without @2xRoscoe
Another solution can be found here angelolloqui.com/blog/20-iPhone5-568h-image-loadingMangan
2Ben: I agree with Sound Blaster, that the @2x suffix shouldn't be there. It's because calling it with the suffix doesn't initialize the correct image scale for retina display (imageNamed checks if there is file with suffix and if there is one, it loads image from file and set scale=2). Just try to run NSLog(@"%f",[UIImage imageNamed:"Default.png"].scale); and NSLog(@"%f",[UIImage imageNamed:@"[email protected]"].scale) on retina device/simulator and You should see the results.Downstairs
you can name it whatever you want... -568@2x or -568 or -568h... It's just you only have one... there's no -568 and -568@2x at the same time, i think that's what Ben was trying to say. In the end it's between you and the designers for a convention for the naming.Virility
@GrizzlyNetch Having tested this some more, you are right. File should be called [email protected], but in code you should say myImage-568h.png. Updated my answer.Finnie
What about this article? I checked the approach, and it does not work, thought. Just wonder how this guy has achieved it...Decalcomania
W
11

The iPhone 5 does not introduce a new pixel density so you can just use all the retina images you used before.

All you need to support the new resolution of the iPhone 5 is to make you views will up the window. For most view, like tableview and scrollview this will not present any problems.

Also there is not need to add an extra XIB files for the new resolution, which is also not supported.

Just add the [email protected] to you apps bundle to make iOS 6 make you app take up the extra space available in the iPhone 5.

All native controls, like the tab bar will behave like you would expect.

If you like to support iOS4.3 and 5.* in you app then make sure that the Use Autolayout in the nib setting (first tab in interface builder) is turned off.

Then make sure you correctly setup the view autoresizingMask

Wien answered 21/9, 2012 at 14:25 Comment(0)
P
1

if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) Exact comparisons of floating point numbers is not a good idea in any language due to rounding errors in the way they are stored in memory. For example, you cannot guarantee 568.0f is not stored as 567.9999999 or 568.0000001. Much safer to use a range, or in this case it would be sufficient to screenHeight > 567.1f. I suspect even the iPhone does not physically support fractions of pixels.

Pyrimidine answered 18/1, 2013 at 8:6 Comment(1)
But fortunately in practice things are not as freaky as you're making them. If using the same compiler on the same platform I'm pretty much sure 568.0 is the same in all representations as long as it doesn't come off of various other operations. Think about it, somewhere in memory the height of the iPhone is declared and returned to your app. There in memory they put 568.0, and then you compare it to 568.0. They use XCode/GCC, you use the same thing, so how could the same compiler put different bits there ?Daveta
R
1

EDIT

BEWARE, as of iOS8 UIScreen take account of the orientation (checking the height can return two value, the portrait height or the landscape height, before it was the portrait height only), but xcassets are better you can check it here : How to addapt iphone background?

END EDIT

Based on ben-clayton answer I made a handy category to manage image for iPhone 5. Thanks.

+ (UIImage *) imageForName:(NSString *)imageName
{
    NSString *result = imageName;

    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    BOOL isIphoneFive = ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f);

    if (isIphoneFive)
    {
        NSString *imageNameWithoutExtension = [imageName stringByDeletingPathExtension];
        NSString *extension = [imageName pathExtension];

        result = [NSString stringWithFormat:@"%@-568h.%@",imageNameWithoutExtension, extension];
    }

    return [UIImage imageNamed:result];
}
Rodriques answered 15/4, 2014 at 19:34 Comment(0)
S
0

I'm currently detecting if current device is a 4" iPhone this way and it works great. hth

- (BOOL)isiPhone5{
    return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568.0);
}
Samala answered 11/2, 2013 at 22:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.