无需 Interface Builder 即可制作通用应用程序

发布于 2024-12-18 05:58:21 字数 769 浏览 2 评论 0 原文

我正在使用 XCode 4.2 和 iOS 5,并且想要制作一个通用应用程序,使用 Interface Builder,如这篇文章 不使用 MainWindow.xib

我还想使用 Kotan Code 的 帖子

因此,我有主 appdelegateappdelegate_iPhone 和继承自它的 appdelegate_iPad

回到 XCode 4.0(以及 Kotan 的帖子中),使用了适当的 appdelegate,因为有一个与之关联的 MainWindow_iPhone.xib (或 MainWindow_iPad.xib)。如果我不使用 .xibs,如何以编程方式转到正确的 appdelegate?

(我希望解决方案不涉及 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {} 等)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对你而言 2024-12-25 05:58:21

看看你的 main.c 文件,它应该包含这样的语句:

int retVal = UIApplicationMain(argc, argv, nil, nil);

其中 UIApplicationMain 定义为:

int UIApplicationMain (
  int argc,
  char *argv[],
  NSString *principalClassName,
  NSString *delegateClassName
);

所以,你只需执行:

int retVal = UIApplicationMain(argc, argv, nil, <YOUR_DELEGATE_CLASS_NAME>);

你的程序将使用它委托类而不是 nib 中定义的类。

还要考虑编辑 info.plist 文件,您应该在其中删除有关您在其中找到的主 nib 文件的所有条目,否则如果从项目中删除 xib 文件,您的程序将崩溃。

编辑:我后来意识到您也在询问如何区分 iPad 和 iPhone...并希望这不涉及检查 UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad

AFAIK,UI_USER_INTERFACE_IDIOM 是执行此操作的官方方法。事实上,如果您检查该宏的定义,您会发现它基于 UIDevice 类,该类返回有关程序运行的设备的信息。所以,我不认为这有什么不好。

另一种方法可能是使用 UIDevice 本身,或 UIDevice-Extension,这是一个扩展 UIDevice 的框架。


编辑2:

对于您在评论中提出的问题:

1)如果有.xibs,我不需要指定UI_USER_INTERFACE_IDIOM
(根据上面链接的 Kotan 帖子)。我必须在笔尖和
这个 if 语句?

我想是的;要么在 xib 级别执行,要么以编程方式执行。

2) 您是否建议我使用 if 语句来跟踪设备
main.m?这是真的,它在那里确实有效。请注意 XCode 4.2 中的更改:

return UIApplicationMain(argc, argv, nil, 
                         NSStringFromClass([AppDelegate class]));

如果您以编程方式执行此操作,则必须在需要的地方执行此操作。

很可能,应用程序委托是应用程序的一部分,不依赖于设备,因此您并不严格需要为 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:

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文