19

我正在尝试将仅 iPhone 的应用程序转换为通用应用程序。我将设备切换到 Universal 并让 Xcode 为我制作 MainWindow-iPad.xib,现在当我在 iPhone 模拟器中运行该应用程序时它工作正常,但是当我在 iPad 模拟器中运行它时我得到一个白色屏幕和Application windows are expected to have a root view controller at the end of application launch错误。我已经阅读了一些关于同样问题的其他帖子,但没有一个仅限于一个设备。

这是我的application:didFinishLaunchWithOptions:方法:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 /* some dropbox setup stuff */


// INIT VIEW AND CORE DATA
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];

NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
    // Handle the error.
}

rootViewController.managedObjectContext = context;

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;

[_window addSubview:[_navigationController view]];
[_window makeKeyAndVisible];

[rootViewController release];
[aNavigationController release];

return YES;
}

编辑:我只有一个大小适合 iPhone 的根视图控制器,称为 RootViewController。但它仍然应该加载,不是吗?或者如果不应该如何为 iPad 创建一个?

4

5 回答 5

52

更改以下行:

[_window addSubview:[_navigationController view]];

至:

_window.rootViewController = _navigationController;

或者,如果您需要 iOS 3 兼容性:

if ([_window respondsToSelector:@selector(setRootViewController:)]) {
    _window.rootViewController = _navigationController;
} else {
    [_window addSubview:_navigationController.view];
}
于 2012-01-03T01:05:29.860 回答
2

在 iOS 4 及更高版本中,UIWindow具有可设置属性rootViewController。这是在应用程序启动UINavigationController时推送显示的内容。UIViewController在 Xcode IB 中,选择Initial Scene: Is initial view controller用于UINavigationController设置所有内容,无需代码。

于 2012-01-04T17:51:47.007 回答
2

你需要用 iPad 的 xib 文件创建一个 RootViewController,否则你会得到这个错误。以下是 Xcode 为通用应用程序提供的模板代码。如果您在 iPad 模拟器中调试应用程序并将调试器指向运行使用 iPhone xib 文件创建视图控制器,您将看到确切的错误。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[SYKViewController alloc] initWithNibName:@"SYKViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[SYKViewController alloc] initWithNibName:@"SYKViewController_iPad" bundle:nil];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}
于 2012-01-03T03:30:01.330 回答
2

从生成的 MainWindow-iPad.xib 中,在 Interface Builder 中,在 IB 中添加一个 View Controller 对象,以及在 View 下面添加一个 Object。对于对象,将其类设置为 AppDelegate,对于视图控制器,将类设置为 ViewController(即身份检查器)并在属性检查器中指定 nib 名称。您可以查看要转换的设备的 MainWindow.nib 以查看差异。

编辑:我忘了提到一些重要的步骤。您还需要在 IB 中将 File's Owner 类设置为“UIApplication”,并为 App Delegate 和 View Controller 设置适当的引用出口。同样,在 IB 中,查看您拥有的 MainWindow nib 的 Connections Inspector 并对其进行仿真是最容易的。如果您有另一个特定于 iPad 的 nib,除了 MainWindow-iPad.nib(即 ViewController-iPad.nib),请务必选择它的 File's Owner 并将其指向视图并适当地设置它的类。

于 2012-09-11T00:14:38.963 回答
0

我尝试了你的建议,但没有一个对我有用,对不起。:/我最终只是在没有界面生成器的代码中手动创建视图:

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    // Setup view for iPad
} else
    // Setup view for iPhone and iPod Touch
}

我认为这比实际上要困难得多。

请注意,如果您使用此方法,您仍然可以在界面构建器中连接所有内容,并且如果您要在 iPhone 和 iPad 上拥有相同的对象,则只需更改这些块中的对象框架。

于 2012-04-06T05:07:19.613 回答