在单个视图控制器中使用多个nib文件?

时间:2012-01-12 17:50:47

标签: ios ios4 uiview interface-builder nib

背景

我正在使用界面构建器为我正在处理的应用创建UI。该应用程序有一个显示一系列按钮的屏幕。单击按钮可显示覆盖按钮的关联视图。单击另一个按钮会隐藏上一个叠加视图并显示另一个。

在IB中管理UI更容易我决定为单击相关按钮时出现的每个子视图创建多个nib文件。然后我使用viewDidLoad类在视图控制器的UINib方法中加载子视图的nib文件。

这背后的想法是避免在单个nib文件中将多个视图堆叠在一起,因为这在IB中很难操作。我本可以在代码中创建所有视图,但这需要大量繁琐的编码,因为每个子视图的布局都非常复杂(有多个子视图)。

从nib文件加载子视图的示例代码。

- (void)viewDidLoad
{
    UINib *aSubViewNib = [UINib nibWithNibName:@"aSubView" bundle:nil];
    NSArray *bundleObjects = [aSubViewNib instantiateWithOwner:self options:nil];

    // get root view from bundle array
    UIView *aSubView = [bundleObjects objectAtIndex:0];
    [self.view addSubview:aSubView];
...

对其他视图重复上述代码。

总结一下,我有一个单屏iPhone应用程序,它具有通过单击按钮显示/隐藏的分层视图。这是通过一个视图控制器实现的,该控制器具有关联的nib文件和一系列用于子视图的附加nib文件,这些文件在视图控制器的viewDidLoad方法中加载。

的问题!

很抱歉很长时间的介绍,但我想非常清楚我在做什么。

  • 我的方法是不好还是不寻常?
  • 这样做有什么潜在的问题吗?
  • 当他们需要动态界面时,其他人做了什么 还想在Interface Builder中保留所有内容吗?

备注

在有人问我为什么不在新屏幕上显示子视图并使用导航栏之前,让我说我有很好的理由,我确实理解iOS UI指南。上面的用例并不完全是我的用例,但它可以清楚地描述问题而不会陷入我的开发应用程序中。

另外我知道我可以把所有的子视图都写成代码,但是每个子视图都有一个复杂的子视图布局,这将是很多代码,并且试图让它们看起来正确。

提前致谢。

3 个答案:

答案 0 :(得分:1)

视图控制器和视图之间不一定存在一对一的关系。大多数视图包含许多子视图,这些视图本身就是视图,所以这实际上没有意义。

但是,根据视图的复杂程度(包括其内容),您可能需要单独的视图控制器...或不。

例如,如果您有两个每个tableViews的sbuviews,您可能希望每个tableView都有一个视图控制器。这是因为每个tableView都在查看相同的委托方法,如果它们位于同一个viewController中,那么委托方法必须区分tableViews。委托方法有签名允许这样做,但是,根据我的经验,它可以真正造成一个难以理解并且难以管理的混乱代码设计。

另一方面,您可能有两个由同一个viewController管理的表,其中一个表填充有意义的数据,另一个表只是一个占位符(如数据源为空时)。一个可能是可见的而另一个则不是。为什么当两个视图控制器都由相同的数据源(模型)驱动时,通过创建两个视图控制器来使生活变得复杂?

在我看来,归结为遵循和管理代码是多么困难。如果使用单个视图控制器的复杂性变得繁重,请考虑使用更多视图控制器。

更新

顺便说一下,我有一个我正在使用的例子,可能会说明类似的情况。在许多开发人员使用的InAppSettingsKit中,有几个xib文件用于主视图的各个部分。 You can look at the structure here on github。有一个主视图控制器和几个xib文件。 (我还称之为“帮助者”视图控制器和电子邮件编辑器视图控制器。)在此示例中,可以多次使用xib文件来指定表视图单元格的布局。但是,每个xib文件都没有视图控制器。 (InAppSettingsKit的文档很稀疏,所以通过快速查看它们可能并不明显。)

答案 1 :(得分:0)

每个视图都应该有一个相应的UIViewController。使用一个ViewController来“控制”多个视图会破坏MVC范例。从一个控制器“控制”多个“视图”将使得在不破坏其他东西的情况下更改一件事变得更加困难。您对如何向最终用户展示内容所做的选择对于每个人来说都是不同的。因此,如果你说一个NavigationController在你的情况下不起作用,也许一个模态视图是答案,或者你可能只是实例化你的自定义UIViewControllers并将它们添加到你的视图([addSubview:]),如果那是你想要的道路,但就像我说的那样,为每个视图对象和相应的xib创建一个“控制器”将是有益的。如果需要发回的信息,请使用委托或使用通知将消息发送回父视图。我学到了不遵循MVC范式的艰难方法,会让你的生活变得悲惨。尝试并尽可能将代码保持分离状态。阅读MVC设计模式,你不会后悔。

答案 2 :(得分:0)

实际上它可以做到这一点。

打开.xib文件,选择文件所有者(占位符) - > “身份检查员”(公用事业) - >将类名更改为您的控制器类名 - >按下控件并将文件的所有者占位符拖动到View对象,在对话框中选择“查看”。 现在您可以自定义视图。

P.S。您可以使用与第一个xib相同的插座,只需将它们拖动到新的xib(+ control sure)。

这是一个解释性的教程: http://irawd.wordpress.com/2013/09/05/how-to-link-a-xib-file-to-a-class-and-use-2-xib-files-for-iphone4-and-iphone5/