I’m using Xcode 4.2 and in the process of writing a universal app. I selected SingleView Application template when starting with a new project. XCode added ViewController1.h, ViewController1.m, ViewController1_iphone.xib and ViewController1_iPad.xib. I need to add more UIs and clicked on the File…New…New File and selected UIViewController subClass template and seeing two checkboxes (Targeted for iPad, With Xib for User Interface).
What should I do here to support both iPad and iPhone while at the same time have a common .h and .m files that share the same code. Do I need to add code to check whether it is a iPad or iPhone by doing this in my view controllers?
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
} else {
}
Also, I have seen people talking about ~iPad and ~iPhone. What is this all about?
If I understand correctly, do I have to design the UI separately both for iPad and iPhone due to different screen sizes?
I’m totally confused here.
Please help.
You can either add two nibs (one for ipad and one for iphone), or you can add one nib that will properly scale for either interface. Normally you’d add two nibs if you’re making a view that will cover all or most of the screen, and you’d add one nib if you’re making something small that will, perhaps, be fullscreen on iphone but displayed in a popover on ipad.
The tilde suffixes
~ipadand~iphoneare described under the heading “iOS Supports Device-Specific Resources” in the Resource Programming Guide. Notice that the suffixes are entirely lower-case, not camel-case as you wrote in your question. This matters because iOS uses a case-sensitive filesystem.When you get a path for a resource using an
NSBundlemessage like-[NSBundle pathForResource:ofType:]or-[NSBundle URLForResource:withExtension:], iOS will first look for the resource file with a suffix of~ipador~iphone, depending on the current device. For example, suppose you do this:If you run this on an iPhone-type device (including an iPod touch), or on the simulator in iPhone mode, iOS will first look in your app bundle for a file named
setup~iphone.plist. If it finds such a file, it will return the path of that file. If it doesn’t find that file, it will instead return the path tosetup.plist.If you this on an iPad-type device, or on the simulator in iPad mode, iOS will first look in your app bundle for a file named
setup~ipad.plist. If it finds such a file, it will return the path of that file. If it doesn’t find that file, it will instead return the path tosetup.plist.All of the other APIs that get resources from bundles are built on top of
NSBundle, so they all benefit from this device-specific lookup. That means if you use+[UIImage imageNamed:], it will automatically use a device-specific image, if you have one in your bundle. And if you use-[NSBundle loadNibNamed:owner:options:], it will automatically load a device-specific nib (.xib) file, if you have one in your bundle.This simplifies your code, if you use the suffixes. If you create
MyViewController~ipad.xibandMyViewController~iphone.xib, your app will automatically load the correct one for the current device. You don’t have to check the user interface idiom;NSBundlechecks it for you. (You could also use the namesMyViewController~ipad.xibandMyViewController.xiband get the same effect.)Now, you may have noticed that when you created your “universal” project, Xcode gave your project files named
ViewController1_iPhone.xibandViewController1_iPad.xib, which do not use the tilde suffixes, and it included code to look at the user interface idiom and choose a filename accordingly. Why does the universal project template do this? I don’t know, but it is stupid. I suggest you fix the filenames to use the tilde suffixes and rip out the code that checks the user interface idiom.