Making universal apps without Interface Builder

爷,独闯天下 提交于 2019-12-03 00:45:32
sergio

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 this if 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 in main.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 ifs 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...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!