在 UISplitViewController 中覆盖 RootViewController.xib

Posted

技术标签:

【中文标题】在 UISplitViewController 中覆盖 RootViewController.xib【英文标题】:Overriding RootViewController.xib in UISplitViewController 【发布时间】:2011-12-19 13:59:36 【问题描述】:

在 iPad 上的 UISplitViewController 设置中,RootViewController 是带有 XIB 文件的 UIViewController 类(不是 UITableViewController。)

我的应用有几个目标。根据选择的目标(以及通过代码中的#ifdef ...),我想为RootViewController 指定一个不同的XIB 文件。

我猜必须在application:didFinishLaunchingWithOptions中进行更改

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

    // Add the split view controller's view to the window and display.
    self.window.rootViewController = self.splitViewController;
    [self.window makeKeyAndVisible];

    return YES;

== 编辑 ==

我从 MainWindow.xib 中删除了所有控制器,然后在 AppDelegate 中添加了以下行。 RootViewController 使用适当的 XIB 启动,但 SplitViewController 中 RootVC 和 DetailsVC 之间的机制不起作用; IE。当点击 RootVC 中应该触发 DefaultVC 更改的按钮时,没有任何反应。我显然错过了一些东西。

splitViewController = [[UISplitViewController alloc] init];

#ifdef OPTION1
    rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController_1" bundle:nil];
#elif OPTION2
    rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController_2" bundle:nil];
#endif

defaultViewController = [[[DefaultViewController alloc] init] autorelease]; 

UINavigationController *rootNav = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];
UINavigationController *defaultNav = [[[UINavigationController alloc] initWithRootViewController:defaultViewController] autorelease];

splitViewController.viewControllers = [NSArray arrayWithObjects:rootNav, defaultNav, nil];
splitViewController.delegate = defaultViewController;

self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];

// Add the split view controller's view to the window and display.
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];

【问题讨论】:

【参考方案1】:

您的代码示例似乎是一种非常困难且令人困惑的拆分视图控制器方式,所以我将只解决更一般的问题:

我的应用有几个目标。根据选择的目标(并通过代码中的 #ifdef ...),我想为 RootViewController 指定不同的 XIB 文件。

如果您在项目中定义了多个目标,则不需要#ifdefs 来执行此操作。使用构建过程的目标机制要简单得多。

假设您有两个资源,都称为“MyFunResource”,但您想在一个名为“blue”的目标中使用一个,另一个您想在一个名为“red”的目标中使用。

将这两种资源添加到您的项目中。但在文件检查器(查看 > 实用程序 > 显示文件检查器)中,请注意名为“目标成员资格”的部分。请注意,您的所有目标都列在那里,旁边有复选框。构建给定目标时,只有在此处选中该目标的名称时,才会将选定资源复制到包中。

因此,选择您想在“红色”目标中使用的“MyFunResource”,并确保“红色”是“目标成员资格”中旁边唯一带有复选标记的东西。然后选择你想要的“蓝色”并确保只选中“蓝色”。

现在,当您构建红色目标时,构建系统只会将与红色相关的资源复制到包中,因此神奇的是,红色资源将在运行时使用。蓝色反之亦然。无需代码或“#ifdef”。

【讨论】:

感谢 Jemmons,这绝对是比我想出的更好的方法。 我希望 Apple 能发布一些关于项目管理的优秀文档(甚至是 WWDC 视频!)。我每天使用的东西太多了,我不得不通过反复试验来发现——其中大部分都在用于 NeXTSTEP 的旧 Project Builder 上!【参考方案2】:

你可以用这个

#ifdef Target1
self.window.rootViewController = [[RootViewController alloc] 
           initWithNibName:@"RootViewControllerTarget1" bundle:nil];
#ifdef Target2
self.window.rootViewController = [[RootViewController alloc] 
               initWithNibName:@"RootViewControllerTarget2" bundle:nil];
// etc...

initWithNibName 使用指定的 .xib 文件初始化控制器。 UIViewController initWithNibName:bundle reference

【讨论】:

谢谢iska,但这行不通,因为rootViewController 将占据所有屏幕。 splitViewController.viewControllers 需要一个包含 2 个控制器的数组; rootViewController 和一个“defaultViewController @Adriano 您是否检查了两个 .xib 文件中的所有插座和连接?还有一件事,它是否适用于一个 .xib 而不是另一个?还是对他们俩都失败了? MainWindow.xib 不再有与其连接的插座,这是因为 splitViewController 现在在 AppDelegate 中以编程方式完成。 rootViewControllers 上的所有插座都连接它对两个目标都有效,但屏幕右侧,defaultViewController 保持未激活状态。【参考方案3】:

我从未发现如何通过 XIB 做到这一点。我最终以编程方式完成了它;我正在使用一个 XIB 并根据目标填充它。

【讨论】:

以上是关于在 UISplitViewController 中覆盖 RootViewController.xib的主要内容,如果未能解决你的问题,请参考以下文章

UISplitViewController:在 detailView 中导航

在 UISplitViewController 中使用 SwiftUI 列表侧边栏

UISplitViewController:为啥我不应该在导航或标签栏界面中显示它?

UISplitViewController 一致分隔符

在 UISplitViewController 中隐藏 MasterView

嵌套详细视图(UISplitViewController)中缺少后退按钮