我有一个刚刚开始实现游戏中心支持的 iOS 应用程序。我在主(根)视图控制器的 loadView 期间调用 authenticateWithCompletionHandler 方法。我的主视图显示,不久后“登录游戏中心”对话框完全按预期出现。如果选择“创建新帐户”,游戏中心的“新帐户”弹出对话框会显示在屏幕中间(这是在 iPad 上)——但我的底层主菜单消失了。弹出对话框下方只是一个黑屏。如果我在完成处理程序中关闭对话框,它会按预期消失,并且我的主菜单会返回。
我认为这一定是某种视图层次结构问题,因此为了简化问题,我创建了一个新项目。使用 Xcode 4.3.2,我通过添加单个视图控制器类“AppViewController”修改了一个新的“空应用程序”iOS 项目。我更改了系统创建的 AppDelegate.m 文件 applicationDidFinishLaunchingWithOptions 方法来设置 rootViewController(在窗口背景颜色设置为白色之后):
self.window.rootViewController =
[[[AppViewController alloc] initWithNibName:nil bundle:nil] autorelease];
...我将 AppViewController 的 loadView 方法设置为加载带有彩色背景的视图(这样我就可以判断它是否在其上正确合成),然后调用 gamekit 身份验证方法:
- (void) loadView {
self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
self.view.backgroundColor = [UIColor yellowColor];
GKLocalPlayer * localPlayer = [GKLocalPlayer localPlayer];
[localPlayer authenticateWithCompletionHandler:nil];
}
这个简单的结构完全模仿了我设置视图层次结构的方式——将单个 UIViewController 设置为加载和管理视图层次结构的窗口 rootViewController。没有 XIB 文件。
无论如何,我使用这个非常简单的测试应用程序得到了完全相同的行为。当“新帐户”弹出对话框出现时,我的底层视图(在本例中为黄色填充)消失(并显示底层窗口白色填充)。我认为这与我对 iOS 希望我如何管理这些控制器和视图的误解有关。
但是,特别奇怪(至少对我而言)是,如果我要么取消“新帐户”窗口,要么使用现有帐户登录,然后立即调出成就弹出对话框(使用 presentModalViewController),这是可行的!我可以在成就对话框后面看到我的主菜单视图。添加一个简单的按钮到视图和按钮按下处理程序到视图控制器显示了同样的事情——成就对话框很好地显示了背景视图,但是“新帐户”对话框掩盖了底层视图。显然,我希望“新帐户”对话框看起来像浮动在我的基础视图之上。我应该提到我正在测试 iOS 5.1。
感谢您能给我的任何帮助!
更新:在听取了另一篇 stackoverflow 帖子的建议后,我购买了 Jeff LaMarche、David Mark 和 Jack Nutting 的“开始 iOS 5 开发”,并查看了有关从 Xcode“空应用程序”模板开始的部分。这导致我稍微修改了我的测试代码。 我现在不是直接设置“rootViewController”属性,而是在 applicationDidFinishLaunchingWithOptions 中执行此操作:
UIViewController * viewController =
[[[AppViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController.view.backgroundColor = [UIColor yellowColor];
[self.window addSubview:viewController.view];
我还摆脱了视图控制器上的上述 loadView 方法。这行得通!有谁知道为什么?我认为这两个系统之间没有实质性区别。在第一个中,我想我正在视图控制器上重新创建视图(第二个系统中的视图控制器视图上没有 alloc/init);自动创建的视图有什么特别之处吗?
更新 x2:好的,看起来真正的区别在于:
[self.window addSubview:viewController.view];
我认为在窗口上设置 rootViewController 会自动将视图添加到窗口中,但除非我明确地这样做,否则我会得到这种奇怪的行为。所以我找到了解决这个问题的方法,我只是不明白它为什么会起作用。有任何想法吗?谢谢!