1
votes

I use bg.png for iPhone, bg@2x for both iPhone retina and iPad, bg@4x for iPad retina. Here is the code i wrote: (in Helper.m)

+ (UIImage *) imageNamed:(NSString *)name
{
    name = [name stringByReplacingOccurrencesOfString:@".png" withString:@""];
    UIImage *image;
    if (IS_IPAD) {
        if (IS_RETINA) {
            image = [UIImage imageNamed:[NSString stringWithFormat:@"%@@4x.png", name]];
            if (image) {
                return image;
            }
        }

        return [UIImage imageNamed:[NSString stringWithFormat:@"%@@2x.png", name]];
    }
    else {
        if (IS_RETINA) {
            image = [UIImage imageNamed:[NSString stringWithFormat:@"%@@2x.png", name]];
            if (image) {
                return image;
            }
        }
        return [UIImage imageNamed:name];
    }
}

The file is correct, but the size of image is wrong.

If the file is automatically picked by the system (use [UIImage imageNamed:@"bg.png"]), then on iPhone retina, the size is still 320x480 (1 point = 4 pixels).

but if i use [Helper imageNamed:@"bg.png"], the size is 640x960. (1 point = 1 pixel)

So anyway to correct the size?

2

2 Answers

8
votes

On a retina device

 [UIImage imageNamed:@"bg.png"]

searches for [email protected] first. If that image exists, it is loaded and the scale property of the image is automatically set to 2.0. On the other hand,

 [UIImage imageNamed:@"[email protected]"]

also loads that image, but uses the default scale = 1.0.

If you have to use a custom loading mechanism, you have to adjust the scale factor. Since scale is a read-only property of UIImage it cannot be set directly. One method I know of is

UIImage *tmpImage = [UIImage imageNamed:@"[email protected]"];
UIImage *properlyScaledImage = [UIImage imageWithCGImage:[tmpImage CGImage]
                                           scale:2.0
                                     orientation:UIImageOrientationUp];
5
votes

Why reinvent what Apple already provides? The imageNamed: method already supports the ability to load iPhone or iPad specific images by using the ~iphone and ~ipad suffixes.

To get an iPad specific retina image you just name it bg@2x~ipad.png. To get an iPad specific non-retina image you name it bg~ipad.png.

The problem you have with your code is due to the non-standard naming conventions, the image is loaded with the wrong scale.

Update: based on additional information in the comments, a better approach to solve this issue is to replace the use of the UIImage imageNamed: method with calls to the UIImage imageWithData:scale: method. This provides better memory management as well as the ability to specify the proper scale for the custom naming conventions and image sharing between iPhone retina and iPad non-retina.