无需 Interface Builder 即可制作通用应用程序
我正在使用 XCode 4.2 和 iOS 5,并且想要制作一个通用应用程序,不使用 Interface Builder,如这篇文章 不使用 MainWindow.xib。
我还想使用 Kotan Code 的 帖子。
因此,我有主 appdelegate
、appdelegate_iPhone
和继承自它的 appdelegate_iPad
。
回到 XCode 4.0(以及 Kotan 的帖子中),使用了适当的 appdelegate,因为有一个与之关联的 MainWindow_iPhone.xib
(或 MainWindow_iPad.xib
)。如果我不使用 .xibs,如何以编程方式转到正确的 appdelegate?
(我希望解决方案不涉及 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {}
等)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看看你的
main.c
文件,它应该包含这样的语句:其中
UIApplicationMain
定义为:所以,你只需执行:
你的程序将使用它委托类而不是 nib 中定义的类。
还要考虑编辑 info.plist 文件,您应该在其中删除有关您在其中找到的主 nib 文件的所有条目,否则如果从项目中删除 xib 文件,您的程序将崩溃。
编辑:我后来意识到您也在询问如何区分 iPad 和 iPhone...并希望这不涉及检查
UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
。AFAIK,
UI_USER_INTERFACE_IDIOM
是执行此操作的官方方法。事实上,如果您检查该宏的定义,您会发现它基于UIDevice
类,该类返回有关程序运行的设备的信息。所以,我不认为这有什么不好。另一种方法可能是使用
UIDevice
本身,或 UIDevice-Extension,这是一个扩展UIDevice
的框架。编辑2:
对于您在评论中提出的问题:
我想是的;要么在 xib 级别执行,要么以编程方式执行。
如果您以编程方式执行此操作,则必须在需要的地方执行此操作。
很可能,应用程序委托是应用程序的一部分,不依赖于设备,因此您并不严格需要为 iphone 实例化一个委托,为 ipad 实例化另一个委托。我指出的是,如果您不提供笔尖,则应该指定一个委托,它只是为您的应用程序定义一个高级入口点。
然后,在您的
– application:didFinishLaunchingWithOptions:
(应用程序入口点)中,您应该创建您的 UI,即创建您将在 nib 中定义的一组对象(控制器、视图等;a nib 只是一种直观地“创建”和连接对象的机制;如果您不以视觉方式进行操作,则可以通过编程方式进行操作)并连接它们;现在,其中一些对象确实依赖于设备(即视图),而另一些则不依赖于设备。对于前者,您可以通过使用UI_USER_INTERFACE_IDIOM
检查来决定从哪个类实例化它们。或者,您可以有两个不同的委托类,一个创建 iphone UI,另一个创建 ipad UI;这也是一个完全合理的做法。这基本上取决于您的应用程序的复杂性以及您愿意接受的权衡。
这或多或少是我看待事物的方式,为可能迂腐而道歉,但我希望我能说清楚。
如果您的应用程序周围有许多
if
,您还可以定义一个“装饰器”函数(例如:decoratedClassNameFromGenericClassName:(NSString*)
,不用介意冗长)来隐藏其中UI_USER_INTERFACE_IDIOM
或将来可能出现的任何其他“装饰”需求......Have a look at your
main.c
file, it should contain a statement like this:where
UIApplicationMain
is defined as:So, you simply execute:
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 aUIDevice
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 extendingUIDevice
.EDIT 2:
To the questions you ask in the comments:
I think so; either you do it at xib level, or programmatically.
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 theUI_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 itUI_USER_INTERFACE_IDIOM
or whatever other "decoration" need might arise in the future...