I'm using XCode 4.2, with iOS 5, and would like to make a universal app, not using Interface Builder, as outlined in this post, not using a MainWindow.xib.
I would also like to separate my iPhone and iPad code, using the technique outlined in Kotan Code's post.
So I have the main appdelegate
, and appdelegate_iPhone
and an appdelegate_iPad
that inherit from it.
Back in XCode 4.0 (and in Kotan's post), the appropriate appdelegate was used because there was a MainWindow_iPhone.xib
(or MainWindow_iPad.xib
) associated with it. If I'm not using .xibs, how do I programatically go to the correct appdelegate?
(I'm hoping the solution doesn't involve if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {}
etc)
Have a look at your main.c
file, it should contain a statement like this:
int retVal = UIApplicationMain(argc, argv, nil, nil);
where UIApplicationMain
is defined as:
int UIApplicationMain (
int argc,
char *argv[],
NSString *principalClassName,
NSString *delegateClassName
);
So, you simply execute:
int retVal = UIApplicationMain(argc, argv, nil, <YOUR_DELEGATE_CLASS_NAME>);
and you program will use that delegate class instead of the one defined in the nib.
Also consider editing the info.plist file, where you should remove all entries about the main nib files you find there, otherwise your program will crash if you remove the xib files from the project.
EDIT: I realized late that you are also asking about how to differentiate an iPad from an iPhone... and hoping this does not involve checking if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
.
AFAIK, UI_USER_INTERFACE_IDIOM
is the official way to do that. Indeed, if you check the definition of that macro you will see it is based on a UIDevice
class that returns information about the device where you program runs. So, I don't see anything bad in it.
An alternative approach might be using UIDevice
itself, or UIDevice-Extension, which is a framework extending UIDevice
.
EDIT 2:
To the questions you ask in the comments:
1) If there are .xibs, I don't need to specify
UI_USER_INTERFACE_IDIOM
(as per Kotan's post linked above). Must I choose between nibs and thisif
statement?
I think so; either you do it at xib level, or programmatically.
2) Are you suggesting I put the
if
statement to track the device inmain.m
? It's true, it does work there. Note the change in XCode 4.2:
return UIApplicationMain(argc, argv, nil,
NSStringFromClass([AppDelegate class]));
If you do it programmatically, you have to do it where you need it.
Likely, the app delegate is a part of the app that does not depend on the device, so you would not strictly need to instantiate one for the iphone and a different one for the ipad. What I was pointing to is that if you are not providing a nib, you should specify a delegate, which simply defines for your app a high-level entry-point.
In your – application:didFinishLaunchingWithOptions:
(the app entry point) you should then create your UI, that is creating that set of objects that you would otherwise define in a nib (controllers, views, whatever; a nib is just a mechanism to visually "create" and connect objects; if you don't do it visually, you do it programmatically) and connecting them; now, some of those objects do depend on the device (i.e., views), others not. For the former ones, you can decide on which class to instantiate them from by using the UI_USER_INTERFACE_IDIOM
check.
Alternatively, you could have two different delegate classes, one that creates the iphone UI and the other the ipad UI; this is also a perfectly reasonable approach. It basically depends on the complexity of your app and what trade-offs you are willing to accept.
This is more or less how I see things, apologies for possibly being pedantic, but I hope I could make myself clear.
If you have many if
s around your app, you could also define a "decorator" function (e.g.: decoratedClassNameFromGenericClassName:(NSString*)
, never mind the verbosity) to hide in it UI_USER_INTERFACE_IDIOM
or whatever other "decoration" need might arise in the future...
来源:https://stackoverflow.com/questions/8274899/making-universal-apps-without-interface-builder