Search code examples
iosios6retina-display

UIImage imageNamed: does not automatically pick retina @2x images


Let's say I have three images in a bundle or asset catalog:

  1. Default~iphone.png
  2. Default@2x~iphone.png
  3. [email protected]

On iOS 4 and later, the UIImage constructor can take the image name as follows:

[UIImage imageNamed:@"Default"];

When I am on a 3.5 inch retina display (iphone) it automatically picks image (2). If on a non-retina display it picks (1). This is great.

I named image 3 as specified for the 4 inch retina (iPhone 5) launch image. Is there a way to name image (3), so that when I am running on a 4 inch retina display, it is returned with the same UIImage constructor?

Perhaps this is not implemented yet, or I expect too much from the convenience... I am just trying to avoid any conditional logic in my code to pick the image based on the screen dimensions.


Solution

  • I also had the same issue and it turned out that there is no such behavior for the iPhone 5/iPod Touch 5th Generation.

    You have to manually determine if your App is running on such a device and change the filename accordingly.

    I've used this method to check if my App is running on an iPhone 5/iPod Touch 5th Gen.:

    #define IS_PHONEPOD5() ([UIScreen mainScreen].bounds.size.height == 568.0f && [UIScreen mainScreen].scale == 2.f && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    

    Then you can adjust the image name like this:

    if(IS_PHONEPOD5()) {
       myImageView.image = [UIImage imageNamed:@"MyImage-568h.png"];
    } else {
       myImageView.image = [UIImage imageNamed:@"MyImage.png"];
    }
    

    Update
    I also found a UIImage category on github (Link) that implements what you're looking for. It does not have a fallback for non existing files, but you could implement it easily by yourself.