I have a project that was intended to be an iPhone app in first instance, but now I want it to also support iPad. I have changed project's target from iPhone to Universal, but I dont know how to manage both nib versions I need now, already having nibs designed for iPhone. I tried by loading same viewControllers with different nibs according to the device, but Im not allowed to set more than one interface control to the same outlets. Any help? I have Xcode 4.4
It's pretty easy.
For your storyboard files, just include the _iPad and _iPhone suffixes.
For example, if the original storyboard name is MyStoryboard.storyboard, you'll now have MyStoryboard_iPad.storyboard and MyStoryboard_iPhone.storyboard. You can also set the storyboard file for each device under the summary view of the project.
Then, for the.xib files, include the ~iPhone and ~iPad suffixes.
ViewController.xib becomes ViewController~iPad.xib and ViewController~iPhone.xib
To start off, you can just create a duplicate if your existing .xib files and rename them to have the iPad and iPhone suffixes. Then alter the contents of each .xib as needed.
As for the .m code, you can check device type and branch your code. My approach is to define macros that identify device type, like this:
#define isDeviceIPad (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
#define isDeviceIPhone (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
Then I just use these macros(which return bool values) to write code that's specific to a device type(such as placement or dimensions of a particular view etc.).
You can change only targeted device as iPhone / iPad and you can use the .xib file of iPad:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
//For navigate to iphone view
}
else{
//For navigate to ipad view
}
Reference
Add 1 more XiB targeted for iPad to each file and during Navigation, select the Xib after checking Device type with the code shown above
Related
I'd like to upgrade my iPhone-only app to Universal. So, from the targets' general window I switch from iPhone to Universal and select "copy" for generate iPad Storyboard based on the iphone one. Now a new folder named iPad is created but is empty and I can't find all of the -ipad classes. What I want is to have all of the original (iPhone) classes duplicated with the -ipad suffix and a iPad dedicated Storyboad. Starting from these classes, and from the iPhone logic I want create step by step a new ipad version. In the targets' general windows ipad main interface is main_iphone-ipad but in the project doesn't exist, in the folder neither.
This isn't an issue with Xcode, thats what its supposed to do.
You can certainly duplicate your entire project for the iPad version manually if you'd like, but I can't think of a case where you'd actually want to do this.
Most of the time you just want to change the View layer between the iPad and iPhone version. You can load a different Nib based on the device you'd like or even load completely different view controllers doing simple logic like
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
viewController = [[MyViewController alloc] initWithNibName:#"ipadNIB" bundle:nil];
} else {
viewController = [[MyViewController alloc] initWithNibName:#"iphoneNIB" bundle:nil];
}
** BEGIN EDIT **
To setup a different storyboard for iPhone/iPad all you need to do is create another storyboard and name it "myprojectname_ipad.storyboard" then in the Info.plist for your project add a key called "Main storyboard file base name (iPad)" with a value "myprojectname_ipad"
** END EDIT **
I have an existing iPad - Application, no I want to make an universal App.
There are many Tutorials with making iPhone Apps universall, but i dont find how to make iPad apps Universal. Is there somebody having experienxce with this?
No Storyboards are used, yust normal xib.
I've readed this tutorial, and porting iPhone apps to universal seems to be better supported by xcode:
http://www.raywenderlich.com/1111/how-to-port-an-iphone-application-to-the-ipad
I would think that the basic idea would be the same, whether you were converting an iPhone app to a universal app, or an iPad app to a universal one(?)
Set the iOS application target to "Universal".
If a view controller, say, XYZViewController has an associated xib for its UI, then - when you create a xib for the iPhone interface - append ~iphone to the name of the iPhone interface and ~ipad to the iPad one, i.e. their file names are
XYZViewController~iphone.xib and XYZViewController~ipad.xib. That way the right xib will be picked up if you pass nil or #"XYZViewController" as nib name to the designated initializer for the view controller. (It's worth noting that the same IBOutlet can be hooked up to the corresponding UI elements in both xibs simultaneously.)
In code, whenever you need to use a different display metaphor that depends on the device type (say you want to use , check for the device type through the test
if ([UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{ ... } else { ... }
Another place where you might want to use this test is in VC's shouldautorotatetointerfaceorientation: method.
I have an iPhone app with
FirstViewController and SecondViewController with respective views FirstView.xib and SecondView.xib.
Now I want to make this app work with both iPhone and iPad. For iPad I need to merge Firstview.xib and SecondView.xib into a single ThirdView-iPad.xib.
What would be the best approach? Do I need to write another ViewController class for iPad or can I use existing FirstViewController and SecondViewController with single xib?
My research so far says that there is no way to use multiple ViewControllers with single xib. Please let me know the best way to do this.
Thanks
if you are using Xcode4 you can use "transition to universal target" and it will do everything needed
http://xcodebook.com/2011/05/making-an-ios-target-universal/
if you dont have it then I recommend to keep controllers out of your xib. xib files will be only containing views for iphone and ipad but the controllers "can" be same. and you can control your logic from the rootviewcontroller, just an idea..it all depends on your project.
You would be best of to just create a new ViewController unless you're into masochism. Reusing in that way would most likely be to much trouble, and I'd go with aggregation or inheritance in the case you need to reuse logic in your ViewControllers.
I typically create a base ViewController, say XYZViewController and then create a XYZViewController_iPhone with all iPhone-specials and a separate XYZViewController_iPad for iPads. But if they're totally different I give them unique names and their own NIBs as well as ViewControllers.
There Are following Rules To Convert The Iphone App to Univarsal App
1) In Plist File Add NSMainNibFile~ipad .... MainWindow_ipad(ipad window).
2) Implement separate Names Xibs (Iphone & ipad)
3)in Target Targeted Device Family set to (iphone/ipad)
and set The Frames According To Ipad &iphone
For example
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
btnHme.frame=CGRectMake(971,6, 32, 32); //ipad
}
else
{
btnHme.frame=CGRectMake(438,6, 32, 32); //iphone
}
cheers
I've been trying all morning to setup a univeral OpenGL-ES app with limited success. I can easily get the default OpenGL template app to compile for both devices and run just fine by adding a new XIB file and setting the proper values in it. Where I'm having trouble is figuring out how to give each device it's own unique GUI. Currently both devices use the same ViewController.xib file that is created with the project. How can I create a separate XIB file that uses the same ViewController .h and .m files? Do I need to create a separate AppDelegate class for each device type, or can they be shared?
The standard approach is to have a base AppDelegate class, and then subclass this for each device. Each delegate would then load its own XIB file with the correctly sized UIWindow and add the views.
You can use a device modifier (i.e., ~ipad) to provide a device-specific key in Info.plist, and to specify a device-specific launch image (Default.png for iPhone, and Default~ipad.png for iPad, for example). Those two things are specifically mentioned in Apple Docs, but they don't say that this will work for any other kinds of files.
I've discovered (quite by accident) that this works for loading .xib files via initWithNibName:bundle:. So for example, I can have MyView.xib and MyView~ipad.xib, and this code:
MyViewController *viewController = [[MyViewController alloc]
initWithNibName:#"MyView" bundle:nil];
... will totally load MyView~ipad.xib on an iPad, and MyView.xib on other devices.
So, 1) Is this documented somewhere? I sure couldn't find it any any Apple docs. It's sure handier than checking UI_USER_INTERFACE_IDIOM() and hardcoding two different nib names everywhere, but I kinda don't trust it if it isn't documented.
And, 2) Does anyone know what version of iOS this started working in? I've only tried it in 4.2, and it works there. Device modifiers in general (even for the documented things listed above) are 4.0 minimum.
I had this same problem. The answer didn't make sense at first, but the good news is that it's easy to do! :)
Just name your iPad xibs without any modifier and your iPhone xibs with ~iphone modifier and it'll select them correctly.
So, with MyViewController, you'll have MyViewController.xib for the iPad and MyViewController~iphone.xib for the iPhone. Then you can just init your view controller with simple alloc/init.
[[MyViewController alloc] init] and it'll grab the right xib.
So, when I create a new view controller in XCode, I always choose the box to format it for ipad, because the xib it will create will be named MyViewController.xib and you want that one to be the iPad sized xib. Then I create a second xib, formatted for iPhone and name it with the ~iphone modifier.
The documentation is a little contradictory at times, but this page talks about how resources with an identifier will default to iPad.
ImageSoundResources
Check the section about using high res images. I know we're talking xibs and not images, but it does work. My last 6 apps have all used this idiom.
Actually, it is explicitly defined in the docs, but as a footnote.
CocoaNibs
In the note at the bottom of "Loading NIB files using NSBundle":
Note: If you are developing a
Universal application for iOS, you can
use the device-specific naming
conventions to load the correct nib
file for the underlying device
automatically. For more information
about how to name your nib files, see
“iOS Supports Device-Specific
Resources.”
Which links to Cocoa Conceptual LoadingResources
However, yes, this is a 4.0+ only feature.
I hate to be that guy and answer my own question, but I think the answer is:
1) Nope, not explicitly documented in any Apple documentation, and
2) 4.0 and higher (this based on my own testing)
All you really save is a couple lines of code checking for UI_USER_INTERACE_IDIOM(). Still, I'll take it. Less code is less code.
The appropriate technique to use in iOS 3.2 and later is the UI_USER_INTERFACE_IDIOM() function. I typically use a ternary operator to init the UIViewController with the appropriate XIB.
UIViewController* controller = [[UIViewController alloc]
initWithNibName:UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ?
#"YourViewController-iPad" : #"YourViewController" andBundle:nil];