29

I'm probably missing something obvious here, yet I've been unable to solve the following problem:

I have a project with image resources for both normal and retina screens, like someimage.png and someimage@2x.png, which are stored in a separate bundle. When I build the project, Xcode automatically packs them into a single multipage tiff (imageName.tiff), I've checked it in finder - it is actually multipage tiff with both images. However, here comes a problem: I struggle to load appropriate resource.

What I do is:

    NSString * imageName = ... ;

    NSLog(@"imageName: %@", imageName);

    UIImage * someImage = [UIImage imageNamed: imageName];

Also I fave auxiliary method, which returns bundle with resources:

   +(NSBundle *) resourcesBundle
   {
         NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"MyResourcesBundle" withExtension:@"bundle"]];
         return bundle;
   }

I've tried following for imageName:

imageName = [[AuxClass resourcesBundle] pathForResource:@"someimage" ofType:@"png"];

in this case i have null for imageName.

imageName = [[AuxClass resourcesBundle] pathForResource:@"someimage" ofType:@"tiff"];

in this case actuall image path is returned, however it only works if I use imageWithContentsOfFile instead of imageNamed, and it doesn't take appropriate resource: it loads resource for retina despite the type of screen.

If I ommit filetype (as I did before adding @2x resources, and it worked ok, and was the first thing I tried and was sure it would work)

imageName = [NSString stringWithFormat: @"%@/%@",
                                  @"MyResourcesBundle.bundle"",
                                  @"someimage" ];

nothing get's loaded.

Adding ".tiff" extension have the same effect as pathForResource: - resource for retina is loaded, disregarding resource for non-retina screen.

So what am I missing? What's the correct way of loading images?

Vladimir
  • 9,683
  • 6
  • 36
  • 57
  • Could you please update question, so people won't be confused with "as expected" in "Xcode automatically packs them into a single multipage tiff (imageName.tiff), as expected (I've checked it in finder - it is actually multipage tiff with both images)". – Luten Nov 07 '14 at 09:09

5 Answers5

48

Have you tried to simply load the image using:

UIImage * someImage = [UIImage imageNamed: @"someimage"];

(assuming your have an image named 'someimage' in you project, for example someimage.png)

The code will automatically pick retina/non-retina versions depending on the platform.

If the problem is that the TIFF are created, check:

XCode Combine high-resolution artwork

In latest version of XCode, go to the Editor menu, then select "validate settings", which should remove that artwork combination.

Resh32
  • 6,500
  • 3
  • 32
  • 40
  • yes, I did try that, but I guess it does not work because there are no "someimage.png" in the bundle - png files are packed into a single multipage tiff – Vladimir Sep 03 '12 at 08:56
  • Maybe I didn't understand why you pack them that way. What is the purpose of that? – Resh32 Sep 03 '12 at 08:58
  • 1
    You can disable that feature, no? BTW check that as well: http://stackoverflow.com/questions/3332981/iphone-sdk-and-multipage-tiff – Resh32 Sep 03 '12 at 09:01
  • it would be nice, however i haven't found it yet – Vladimir Sep 03 '12 at 09:03
  • Check http://developer.apple.com/library/mac/#documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html – Resh32 Sep 03 '12 at 09:05
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/16182/discussion-between-resh32-and-vladimir) – Resh32 Sep 03 '12 at 09:07
  • 1
    Just a tip: you can even remote the file extension from the argument to make it a bit clearer than there is some additional logic going on, and allowing you to change the file format without updating code. – Mike Weller Apr 10 '13 at 10:15
  • The option is called COMBINE_HIDPI_IMAGES for me in Xcode 4.6.2. – hwaxxer Jul 10 '13 at 11:33
  • Thanks for this. In Xcode5, a new "feature" means you cannot edit this setting unless you switch the project to building for OS X. i.e. on iOS, even though this setting is honoured, you cannot turn it off. Switch to "build architectures: OS X", and you can fix the setting, then switch back to iOS. – Adam Nov 25 '13 at 15:36
  • If the resource is in bundle you should provide it as path: UIImage * someImage = [UIImage imageNamed: @"MyResourcesBundle/someimage"]; – Luten Oct 30 '14 at 10:56
11

Multipage TIFFs are only for OSX; they don't work on iOS.

So you need to stop trying to access resources that are, by their very nature, inaccessible, and do things the right way!

You need to open the project that generates the external resources bundle, select the target, go to Build Settings and then the Deployment sub-heading, and set "Combine High Resolution Artwork" to No. Then recompile the external resources bundle.

In your main project you should now be able to read in the PNGs in the normal manner.

Luten
  • 5,420
  • 4
  • 26
  • 24
Wildaker
  • 2,533
  • 1
  • 17
  • 19
  • 4
    Ok, I figured out the issue. If you don't see the setting, in the bundle settings change base SDK to Mac OS X, then change the setting to no, and change base SDK back to iOS. Even though the option is not available it seems to still be applied during build time. – Emilis Panovas Sep 07 '12 at 20:11
  • 2
    I search the build settings for "combine" and found "COMBINE_HIDPI_IMAGES" which was set to "YES". I set it to "NO" and it stopped combining the images. – Walt Sellers Mar 22 '13 at 04:26
11

If you are working with bundles than go to

-> build settings -> COMBINE_HIDPI_IMAGES to NO,

and you just need to clean and build!

Jignesh Rajput
  • 3,538
  • 30
  • 50
casero
  • 121
  • 1
  • 2
2

-> build settings -> COMBINE_HIDPI_IMAGES to NO

this is the only solution that works and no other change is necessary

1

When you are creating images for your app, let's say you're creating an image called example.

You should save the following:

  • example~iphone.png -> this is for non retina iPhone
  • example~iphone@2x.png -> this is for retina iPhone
  • example~ipad.png -> this is for non retina iPad
  • example~ipad@2x.png -> this is for retina iPad

So, it doesn't matter from where you call it, you just call it this way, assuming myImageView is a UIImageView object:

[myImageView setImage:[UIImage imageNamed:@"example"]];

Apple strongly recommends you to use png images. Also, the OS takes care of finding the correct image for the desired device. You don't need to worry about finding the path and all that stuff. +(UIImage*)imageNamed:(NSString*)name looks for the correct image in your resources bundle - and by the way, to return the bundle with your resources just call [NSBundle mainBundle];

Arnlee Vizcayno
  • 2,405
  • 3
  • 23
  • 31
Natan R.
  • 5,141
  • 1
  • 31
  • 48
  • well I that's basically the first thing i tried - and it eludes me why this doesn't work. i do use png images - they are packed into tiff by xcode automatically. i don't use `[NSBundle mainBundle]` because i have a separate bundle for the image resources. – Vladimir Sep 03 '12 at 09:00