12

I know there were some discussions about this but i could not find good answer?

My questions are -

  1. I know that -

      [UIImage imageNamed:@"blabla"]
    

will automatically search for the correct image to display (retina or not) on iPhone.

I have a Universal app, and i wish to use the @2x versions on the ipad so i wont have to load an other version of the images (I have hundreds of small images).

is it possible ?

  • I saw in some places that people wrote that apple discourage Universal apps as it prefers building separated apps for iPhone and iPad ? is that correct even when i create a different UI for each?

thanks

shani

shannoga
  • 19,649
  • 20
  • 104
  • 169
  • Why would Apple prefer distinct iPad and iPhone apps? As a user, universal apps are _much_ more appealing to me. – Aidan Steele Feb 23 '11 at 09:27
  • thats why i thought when decided to go for universal app but i saw it in some places and just want to be sure – shannoga Feb 23 '11 at 09:30

4 Answers4

66

If you're loading an image named "image" the search paths are likely to be the same as they've always been:

iPhone:

  • 1) image@2x~iphone.png (retina only)
  • 2) image@2x.png (retina only)
  • 3) image~iphone.png
  • 4) image.png

iPad:

  • 1) image@2x~ipad.png (retina only)
  • 2) image@2x.png (retina only)
  • 3) image~ipad.png
  • 4) image.png
JohannaVL
  • 761
  • 1
  • 5
  • 4
  • If this works, this should be the selected answer. This is awesome. Of course, you may want to note that this only works on 4.0+. http://stackoverflow.com/a/5535913/362730 – Tim Nov 18 '12 at 18:48
  • Also - this means that if you have regular iPhone size, Retina iPhone size, and regular iPad graphics, that a retina iPad would prefer to load Retina iPhone graphics before regular iPad graphics? – Tim Nov 18 '12 at 19:01
  • what is the difference between in iPhone: 1) image@2x~iphone.png (retina only) 2) image@2x.png (retina only) – hariszaman Jul 14 '15 at 09:36
  • @JohannaVL If that's the case then what will be the size of them. image~ipad.png & image@2x~ipad.png (retina only) for 44 x 44 px > 1x image? – Tulon Jun 02 '16 at 12:50
17

There is no good built-in way of not duplicating the higher res iphone retina images for the iPad. You could write your own UIImage extension or subclass that uses the user interface idiom macro to determine your platform, then automatically append "@2x" to the image name:

+ (UIImage *) imageNamedSmart:(NSString *)name
{
    if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
        return [UIImage imageNamed:[NSString stringWithFormat:@"%@@2x.png", name]];
    return [UIImage imageNamed:[NSString stringWithFormat:@"%@.png", name]];
}

and you'd call it like this:

[UIImage imageNamedSmart:@"myImage"]
Stig Brautaset
  • 2,602
  • 1
  • 22
  • 39
Bogatyr
  • 19,255
  • 7
  • 59
  • 72
  • Hey my mistake. the truth is that that was my first try. but i was stupid enough to try it on a view that i still don't have the @2x images for it. thanks any way :) – shannoga Feb 24 '11 at 05:41
  • Excellent and thanks! Just added my first class extension and it works like clockwork :-) Just had to add a ] at the end of the second return statement. – Structurer May 14 '11 at 05:51
  • Thanks! ( Just a small observation: the method should be a Class Method, not an Instance Method :p ) – Fede Mika Jul 07 '11 at 22:10
  • also i believe it's called a category and not an extension or maybe you're doing something different. – nickthedude Jul 29 '11 at 00:01
  • is there any way to use this from xib ? – AmineG Apr 17 '12 at 10:40
  • @someone0: not directly that I know of. The image filename specified in the xib will go through the "retina" check automatically, but unfortunately there is no automatic ~ipad.png for ipad. – Bogatyr Apr 17 '12 at 14:14
  • Does this code work on an old iPad?? Is it correct to always include "@2x" in the filename? – ragnarius Apr 28 '12 at 22:40
  • 1
    @ragnarius yes the whole point was to have it work on the old ipad. With the new retina ipad a slightly different approach would be needed I imagine. – Bogatyr Apr 29 '12 at 09:33
  • why couldn't you just subclass `UIIImage` and then override `imageNamed:`? Then take the string passed to the method, do your checks and change it accordingly, and call `[super imageNamed:]`? – Marty Jun 04 '12 at 07:27
  • I suppose you could, but then some code must explicitly change to use the new subclass. Categories add functionality to existing classes. – Bogatyr Jun 04 '12 at 09:37
  • @2x means retina... not ipad so now you are using an iPhone retina image on an ipad. What if the ipad supports retina? – Bot Aug 13 '12 at 22:37
  • 1
    This question came in at a time when there was no retina for ipad, and developers typically wanted to use the same artwork for retina iphone and non-retina ipad. It still remains valid for this case -- using the same file for both iphone and non-retina ipad. For retina ipad, presumably you want new artwork, and would need to adjust the routine to add in a "-ipad...@2x" or whatever you use for naming your ipad retina images. – Bogatyr Aug 15 '12 at 11:29
3

I improved on Bogatyr's answer by checking if the retina image exists. Probably not overly necessary, but I found it useful when testing so I can just create one image file.

+ (UIImage *) imageNamedSmart:(NSString *)name {
    NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
    NSString *retinaFileName = [NSString stringWithFormat:@"%@@2x", name];

    NSString *filePath = [[NSBundle mainBundle] pathForResource:retinaFileName ofType:@"png"];

    if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && [fileManager fileExistsAtPath:filePath]) {
        return [UIImage imageNamed:[retinaFileName stringByAppendingString:@".png"]];
    }
    return [UIImage imageNamed:[NSString stringWithFormat:@"%@.png", name]];
}
Chilly
  • 743
  • 8
  • 7
0

Maybe you can duplicate all images resources image@2x.png to image~ipad.png. Be careful to the case of "~ipad.png". But you have to manually manage stretched image with Cap (stretchableImageWithLeftCapWidth: topCapHeight:).

Starter
  • 86
  • 1
  • 2