13

I place a play.png image onto my view. When the view initially loads, the iPhone 4 grabs the corresponding play@2x.png file and it looks great. However, when I tap the play button my code swaps it out for the pause.png file. Then, when I tap the pause.png to bring back the play.png it uses the original play.png file (not the @2x version like I thought it would automatically reference).

This is the code I tried to use:

[button setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];

So, if I swap files after the initial view load, do I have to manually specify the @2x version inside an IF statement? If so, is the UIScreen.scale the best attribute to use for this?

I'm currently using code like this:

if ([UIScreen mainScreen].scale > 1.0) 
{ 
    [button setImage:[UIImage imageNamed:@"play@2x.png"] forState:UIControlStateNormal]; 
} 
else 
{ 
    [button setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; 
}

It's working fine but having the IF statement in there is annoying and seems a little fragile.

Thanks in advance to all you smarties out there.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
nicjohnson
  • 624
  • 1
  • 6
  • 11
  • 1
    Please post how you swap images... `UIImage imageNamed` normally handles it automagically whereas other methods don't (yet) – iwasrobbed Aug 09 '10 at 17:28
  • [button setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; – nicjohnson Aug 09 '10 at 20:37
  • for now I'm using the following (sorry, I can't figure out how to format the code as code): if ([UIScreen mainScreen].scale > 1.0) { [button setImage:[UIImage imageNamed:@"play@2x.png"] forState:UIControlStateNormal]; } else { [button setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal]; } It's working fine but having the IF statement in there is annoying and seems a little fragile. – nicjohnson Aug 09 '10 at 20:47
  • @nicjohnson - I inserted the code from your comments in the question. Hopefully, I conveyed your meaning properly. In the future, you should be able to edit your questions to insert code like this, then format it using the code option in the editing toolbar above the text (or using four spaces before each line of code). – Brad Larson Aug 09 '10 at 22:09
  • Thanks, Brad. So, as far as you know, imageName should be able to reference play.png and auto-swap the @2x version even if I'm switching back and forth between play.png and pause.png? – nicjohnson Aug 11 '10 at 04:24
  • I has similar problem. Got it solved using below link. http://stackoverflow.com/q/6136985/1753005 – Jayprakash Dubey Mar 06 '13 at 05:46

9 Answers9

25

The conditional statement is unnecessary. The following line is sufficient:

[button setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];

In iOS 4.0, the imageNamed: method automatically looks for the "@2x" filename suffix if the device is an iPhone 4 and has the retina display. In previous versions of iPhone OS, the imageNamed: method only looks for what you write (i.e., the lower-resolution image). This works because the iPhone 4 can't have a lower OS version then 4.0, so your retina display users will always have the higher resolution artwork.

Arseniy Banayev
  • 686
  • 9
  • 18
  • You'll notice from my initial post that the line of code you gave me is exactly what I was using. It initially loaded the retina version of the play icon, but when I tapped it and swapped it with pause.png then back to play.png it would then use the low-res version of play.png. – nicjohnson Aug 12 '10 at 13:50
  • 1
    Unfortunately, the code you're describing should work fine, so I think the problem is somewhere else in your project. I just made a button with two images and on each click it switches; works fine. Could you post all the code involving this button? – Arseniy Banayev Aug 12 '10 at 16:26
8

You can use just:

[UIImage imageNamed:@"play"]

Without the extension. This will load the @2x version if available and if the device has a x2 scale.

This will work for iOS4 or grater. However if you want to run your application in previous versions you could do the following:

UIImage* image = [UIImage imageNamed:@"play"]; // for iOS 4 or greater
if(!image)
    image = [UIImage imageNamed:@"play.png"]; // for previous iOS versions

The benefit is that this will work if at any moment you have @3x or any other version if Apple creates new devices or displays.

You can create an utility method to avoid doing this everywhere you need to load an image.

See: Supporting High-Resolution Screens, section "Loading Images into Your Application"

gimenete
  • 2,649
  • 1
  • 20
  • 16
4

Two silly mistakes (both of which I've made before) that can cause this problem:

  1. Accidentally naming the small versions @2x instead of the large ones
  2. Having the large versions be slightly missized (by one pixel)
AlcubierreDrive
  • 3,654
  • 2
  • 29
  • 45
3

I ran into the same problem, then realized that my Windows Photoshop-exported .png files were .PNG files. Apparently the capitalization does matter.

Also see Hi-Res @2x image not being picked up for tab bar item

Community
  • 1
  • 1
ine
  • 14,014
  • 8
  • 55
  • 80
2

I can confirm that this is a problem with the 4.0 device. The problem is not that it does not load the @2x image, it does indeed, but still displays it at 72 DPI (causing it to be blurry).

This bug is fortunately fixed in 4.1 (tested in the emulator).

Marius
  • 3,372
  • 1
  • 30
  • 36
1

Someone on another thread mentioned that they managed to solve a similarly vexing problem by deleting and re-adding their hi-res images to the project.

Tim K
  • 333
  • 3
  • 9
0

I had a similar problem when I replaced a low res icon-close.png with high res icon-close@2x.png. iPad builds seemed to ignore the "@2x" and loaded the image at double size with scale = 1.0. Removing the file and adding back did not help. Renaming it to "icon-leave@2x.png" did. Some bad info cached somewhere about icon-close.png

user1055568
  • 1,349
  • 13
  • 21
0

I had similar issue because of filename - button_slice9.png and button_slice9@2x.png didn't work.

But button_slice.png and button_slice@2x.png works as expected in imageNamed:.

adruzh
  • 1,045
  • 9
  • 17
0

I just had a similar problem that took a while to figure out. It turns out that my @2x images somehow weren't added to my app target, so they weren't being packaged.

ja41
  • 171
  • 1
  • 7