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!

Andrey
  • 2,659
  • 4
  • 29
  • 54

5 Answers5

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 myImage-568h@2x.png. If you don't do this, then the scale is incorrect, just like they said.

FeifanZ
  • 16,250
  • 7
  • 45
  • 84
Ben Clayton
  • 80,996
  • 26
  • 120
  • 129
  • 2
    I think, right image name is 'myImage-568h.png' - without @2x – Sound Blaster Sep 25 '12 at 12:00
  • 2
    Another solution can be found here http://angelolloqui.com/blog/20-iPhone5-568h-image-loading – Angel G. Olloqui Sep 30 '12 at 10:46
  • 1
    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:@"Default@2x.png"].scale) on retina device/simulator and You should see the results. – JakubKnejzlik Nov 04 '12 at 16:50
  • 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. – LolaRun Jan 14 '13 at 09:36
  • 1
    @GrizzlyNetch Having tested this some more, you are right. File should be called myImage-568h@2x.png, but in code you should say myImage-568h.png. Updated my answer. – Ben Clayton Jan 15 '13 at 16:39
  • What about [this](http://www.smartersoftware.de/wordpress/2013/02/using-imagenamed-to-pick-the-right-image-file/) article? I checked the approach, and it does not work, thought. Just wonder how this guy has achieved it... – Yevhen Dubinin Jul 05 '13 at 08:52
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 Default-568h@2x.png 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

rckoenes
  • 69,092
  • 8
  • 134
  • 166
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.

  • 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 ? – RelativeGames Feb 23 '13 at 08:12
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];
}
Community
  • 1
  • 1
Boris Charpentier
  • 3,515
  • 25
  • 28
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);
}
link82
  • 31
  • 1
  • 4