Is it possible to have an image asset named architecture.png and rename it as architecture~ipad.png for the iPad version? And still use it in code as:
[UIImage imageWithName:#"architecture.png"];
will this then look for architecture~ipad for the iPad version?
If you have two image resources in your app:
"architecture.png" (iPhone version)
"architecture~ipad.png" (iPad version)
then
[UIImage imageWithName:#"architecture.png"]
will automatically load the correct one on iPhone/iPad devices.
(As DOOManiac correctly noticed, this works on iOS 4 and later.)
For more information, see "iOS Supports Device-Specific Resources" in the Resource Programming Guide.
Update:
From the link iOS Supports Device-Specific Resources, It looks like this is possible from iOS 4.0 onwards.
In iOS 4.0 and later, it is possible to mark individual resource files
as usable only on a specific type of device. This capability
simplifies the code you have to write for Universal applications.
Rather than creating separate code paths to load one version of a
resource file for iPhone and a different version of the file for iPad,
you can let the bundle-loading routines choose the correct file. All
you have to do is name your resource files appropriately.
To associate a resource file with a particular device, you add a
custom modifier string to its filename. The inclusion of this modifier
string yields filenames with the following format:
<basename><device>.<filename_extension>
The <basename> string represents the original name of the resource
file. It also represents the name you use when accessing the file from
your code. Similarly, the <filename_extension> string is the standard
filename extension used to identify the type of the file. The <device>
string is a case-sensitive string that can be one of the following
values:
~ipad - The resource should be loaded on iPad devices only.
~iphone - The resource should be loaded on iPhone or iPod touch
devices only.
You can apply device modifiers to any type of resource file. For
example, suppose you have an image named MyImage.png. To specify
different versions of the image for iPad and iPhone, you would create
resource files with the names MyImage~ipad.png and MyImage~iphone.png
and include them both in your bundle. To load the image, you would
continue to refer to the resource as MyImage.png in your code and let
the system choose the appropriate version, as shown here:
UIImage* anImage = [UIImage imageNamed:#"MyImage.png"]; On an iPhone
or iPod touch device, the system loads the MyImage~iphone.png resource
file, while on iPad, it loads the MyImage~ipad.png resource file. If a
device-specific version of a resource is not found, the system falls
back to looking for a resource with the original filename, which in
the preceding example would be an image named MyImage.png.
For devices which supports iOS < 4.0, you can follow the below approach. But I dont think it is needed any more. Still keeping it as it is.
One solution I can think of is, by defining a macro for iPad to append ~ipad.png for every image files. Then always call this macro while using this method as [UIImage imageWithName:imageName(#"architecture")]; which will convert it as [UIImage imageWithName:#"architecture.png"]; for iPhone and [UIImage imageWithName:#"architecture~ipad.png"]; for iPad.
For eg:-
#define IMAGENAME(Name) (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)?[(Name) stringByAppendingString:(#"~ipad.png")]:[(Name) stringByAppendingString:(#".png")]
and then use it as [UIImage imageWithName:IMAGENAME(#"architecture")];
it can also be defined as,
#define IMAGENAME(Name) (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)?[(Name) stringByReplacingOccurrencesOfString:#".png" withString:#"~ipad.png"]:(Name)
and then use it as [UIImage imageWithName:IMAGENAME(#"architecture.png")];
Another solution is to subclass UIImage class and override imageWithName method to have this logic implemented here. You need to search for .png in the name param and replace it with a ~ipad.png for iPad. After that you can directly use it as [UIImage imageWithName:#"architecture.png"] for both iPad and iPhone. This can also be achieved by creating a category on NSObject or UIImage. I dont think there are any other ways to achieve this.
Related
i'm sorry for my english.
i'm new in iphone development and happens to me a strange things.
I have a set of jpg images to show in a table view. When i test the app in iphone simulator everything is ok and work properly but when built and run the same code in iphone test device the same images aren't displayed.
Another strange behavior is that with a set of png images instead of jpg are shown perfectly in simulator like as in iphone test device.
Anyone can suggest me a solution?
I detect the name of image to load from a json file. This is the code that i use to show the image:
UIImageView *immaginePiadina = [[UIImageView alloc] initWithFrame:immagineValueRect];
[immaginePiadina setImage:[UIImage imageNamed:[item objectForKey:#"immagine"]]];
where [item objectForKey:#"immagine"] is an element of my json file like this:
"nome": "66",
"immagine": "pianetapiadabufalavesuviani",
"prezzo": "€ 7,50",
"nomeingrediente": [
"bufala",
"vesuviani"
]
How you can see i refer to the image with only the name of the file and without the file extension. I did it in this way to show image retina, it's wrong?
I exclude that i wrote a different case sensitive name because the png set works properly.
thanks a lot!!
There are possibly two separate issues that need separation, here is how to solve your problem.
First write a method using the NSFileManager, that given a file path verifies a file exists and has a size greater than 0. Insert a call to this everywhere you fail to open an image. If you use "imageNamed" then get the path to the bundle and create the path. If this method fails to find an image, fix it.
Second, the image decoding is different for the simulator and the device - the simulator uses the full OSX libraries. So take one image that fails to open and move it somewhere. Open it in Preview and export it using the same name but with png+alpha format. Change your code to expect a png not a jpg, and retest. Make sure you still use the first method to insure the file is there.
Once you get one success you can try other options, like using Preview exported jpegs. The reason this should work is that all of these image formats permit a huge range of options all of which iOS does not support.
Given that the current format us the problem, you can script changes using the "sips" program, which is what Preview uses.
I solve my problem using the following code:
NSString* path = [[NSBundle mainBundle] pathForResource:[item objectForKey:#"immagine"] ofType:#"jpg"];
NSLog(#"%#",path);
UIImage* theImage = [[UIImage alloc] initWithContentsOfFile:path];
I don't know the reason but in this way i haven't any problem to display jpg in my iPhone test device. Maybe because NSBundle specify also the extension of the file.
Thanks #David-h that directed me in the right way to solve my problem.
Check the extensions of your images. If you write .PNG, in the simulator is Ok, but not in the device.
I want to create an application that work with iphone 3 and 4.
so I have images for iphone 3 and others for 4.
now I want my application to load resources based on ios version
the part of detecting ios version is easy.
the problem is that i want to know how to create new NSBundle and use it to make application load resources from different bundle based on detected ios version.
if your resource is only concerned with image then you are not required to put any extra effort to do that. Suppose you have a image named myHome.png for 3 then rename the same image for 4 to myHome#2x.png. It will automatically take that image if the device is iPhone4.
If the resource is any thing other than image then you need to do conditional coding i.e you need to check for a condition every time you are trying to access such resource and the code will look something like this
1 to check if its iPhone of iPad do this
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:#"iPhone"])
{
//do your work for iPhone
}
2 To check between iOS version you can try this link this the best I know
I am developing one application. In that I want to save my pictures in camera roll. So how to save my pictures in camera roll through code?
The most basic way (and the only way if you're targeting iOS before 4.0) is to use UIImageWriteToSavedPhotosAlbum. This lets you specify a selector to be called on a target object when the save is complete.
In 4.0, you can use ALAssetsLibrary's writeImageToSavedPhotosAlbum:orientation:completionBlock: to write the image; in this case, you provide a block to be called when the save is complete.
In 4.1, you can also use ALAssetsLibrary's writeImageDataToSavedPhotosAlbum:metadata:completionBlock: or writeImageToSavedPhotosAlbum:metadata:completionBlock: to write an image along with metadata (e.g. geotagging information). The former is also the only way to write an image from an NSData object without first loading it as a UIImage or CGImageRef.
See this blog post..UIImageWriteToSavedPhotosAlbum is your friend..
We are using the MPMoviePlayerController to control video playback, I just wanted to know (as I couldnt find any mention online) whether it took advantage of #2x files when displayed on iPod4/iPhone4, like the UIImage does
No, #2X it's only for UIimages.
It doesn't do it automatically like UIImage will. But you could always implement a system your self. Using a subclass, category or just in your current code before set what file is played by the movie player. So the code would be something like. If it has a retina display append #2x to the file path.
I want to create application, that will process images(mostly - photographs from mobile camera).
So i need at first to provide the way to open image file from phone memory.
how can i do that?
Sorry for such a stupid question, but i am newbie in iphone programming(yet:)).
P.S. I use xcode, cocoa
You can use UIImagePickerController to get a standard interface for selecting a photo from the user's library or camera roll. Depending on the configuration, it can also be used to capture a new image with the camera. Note however that you get a UIImage back, not a file, if you want to upload it somewhere, you will first have to create a file or NSData object from the image, using either UIImagePNGRepresentation() or UIImageJPEGRepresentation().