简体   繁体   English

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

[英]Using multiple nib files with a single view controller?

Background 背景

I'm using interface builder to create the UI for an app I'm working on. 我正在使用界面构建器为我正在处理的应用程序创建UI。 The app has a single screen that displays a series of buttons. 该应用程序有一个显示一系列按钮的屏幕。 Clicking on a button displays an associated view which overlays the buttons. 单击按钮可显示覆盖按钮的关联视图。 Clicking another button hides the previous overlay view and displays another one. 单击另一个按钮会隐藏上一个叠加视图并显示另一个。

Too make managing the UI easier in IB I've decided to create multiple nib files for each sub view that is to appear when clicking the relevant button. 在IB中更容易管理UI我决定为每个子视图创建多个nib文件,这些文件在单击相关按钮时显示。 I'm then loading the sub view's nib file in the view controller's viewDidLoad method using the UINib class. 然后我使用UINib类在视图控制器的viewDidLoad方法中加载子视图的nib文件。

The idea behind this was to avoid having multiple views stacked on top of each other in a single nib file as this would be hard to manipulate in IB. 这背后的想法是避免在单个nib文件中将多个视图堆叠在彼此之上,因为这在IB中难以操纵。 I could have created all the views in code but this would require a lot of tedious coding as the layouts of each sub view are quite complex (with multiple child views). 我本可以在代码中创建所有视图,但这需要大量繁琐的编码,因为每个子视图的布局都非常复杂(具有多个子视图)。

Example code loading a sub view from a nib file. 从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];
...

The code above is repeated for the other views. 对于其他视图重复上面的代码。

To summarise I have a single screen iPhone app that has layered views that are shown/hidden by clicking buttons. 总结一下,我有一个单屏iPhone应用程序,它具有通过单击按钮显示/隐藏的分层视图。 This is achieved with a single view controller with an associated nib file and a series of additional nib files for the sub views which are loaded in the view controller's viewDidLoad method. 这是通过单个视图控制器实现的,该控制器具有关联的nib文件和一系列用于子视图的附加nib文件,这些文件在视图控制器的viewDidLoad方法中加载。

Questions! 问题!

Sorry for the long introduction but I wanted to be very clear what it is I am doing. 很抱歉很长时间的介绍,但我想非常清楚我在做什么。

  • Is my approach bad or unusual? 我的方法是不好还是不寻常?
  • Are there any potential issues to doing it this way? 这样做有什么潜在的问题吗?
  • What have other people done when they need a dynamic interface and still want to keep everything in Interface Builder? 当其他人需要动态界面并且仍想在Interface Builder中保留所有内容时,他们做了什么?

Notes 笔记

Before anyone asks why don't I just display the sub views on a new screen and use the navigation bar, let me say that I have very good reasons and I do understand iOS UI guidelines. 在有人问我为什么不在新屏幕上显示子视图并使用导航栏之前,让我说我有很好的理由,我确实理解iOS UI指南。 The above use case is not exactly my use case but it's one that clearly describes the problem without getting bogged down in my development app. 上面的用例并不完全是我的用例,但是它可以清楚地描述问题而不会陷入我的开发应用程序中。

Also I know I could have written all the sub views as code but each sub view has a complex layout of child views and it would be a lot of code and messing around to try and get them looking right. 另外我知道我可以将所有子视图编写为代码,但每个子视图都有一个复杂的子视图布局,这将是很多代码和乱七八糟的尝试让他们看起来正确。

Thanks in advance. 提前致谢。

There isn't necessarily a 1-to-1 relationship between view controllers and views. 视图控制器和视图之间不一定存在一对一的关系。 Most views contain many subviews, which are views themselves, so this literally doesn't make sense. 大多数视图包含许多子视图,这些视图本身就是视图,所以这实际上没有意义。

However, depending on the complexity of the views (including their content), you may want separate view controllers... or not. 但是,根据视图的复杂程度(包括其内容),您可能需要单独的视图控制器...或不。

For example, if you have two sbuviews that are each tableViews, you may want to have one view controller for each tableView. 例如,如果您有两个每个tableViews的sbuviews,您可能希望每个tableView都有一个视图控制器。 This is because each tableView is looking at the same delegate methods, and if they are in the same viewController, then the delegate methods have to differentiate between the tableViews. 这是因为每个tableView都在查看相同的委托方法,如果它们位于同一个viewController中,那么委托方法必须区分tableViews。 The delegate methods have signatures that allow this, but, in my experience, it can really make for a messy code design that is hard to follow and hard to manage. 委托方法有签名允许这样做,但是,根据我的经验,它可以真正造成一个难以理解和难以管理的混乱代码设计。

On the other hand, you may have two tables that are managed by the same viewController, where one table is filled with meaningful data and the other is simply a place holder (as when the data source is empty). 另一方面,您可能有两个由同一个viewController管理的表,其中一个表填充有意义的数据,另一个表只是一个占位符(如数据源为空时)。 One might be visible while the other is not. 一个可能是可见的而另一个则不是。 Why make you life complicated by creating two view controllers when both are driven by the same data source (the model)? 为什么当两个视图控制器由相同的数据源(模型)驱动时,通过创建两个视图控制器使您的生活变得复杂?

In my mind, it comes down to how difficult it is to follow and manage the code. 在我看来,它归结为遵循和管理代码是多么困难。 If the complexity of using a single view controller becomes burdensome, consider using more view controllers. 如果使用单个视图控制器的复杂性变得繁重,请考虑使用更多视图控制器。

UPDATE UPDATE

By the way, I have an example that I am currently working with that may illustrate a similar situation. 顺便说一下,我有一个我正在使用的例子,可以说明类似的情况。 In the InAppSettingsKit, that a lot of developers use, there are several xib files for pieces of the main view. 在许多开发人员使用的InAppSettingsKit中,有几个xib文件用于主视图的各个部分。 You can look at the structure here on github . 你可以在github上看一下这里的结构 There is one main view controllers and several xib files. 有一个主视图控制器和几个xib文件。 (There is also what I would call a "helper" view controller and an email composer view controller.) In this example, the xib files may be used multiple times to specify the layout of table view cells. (我还称之为“帮助者”视图控制器和电子邮件编辑器视图控制器。)在此示例中,可以多次使用xib文件来指定表视图单元格的布局。 There is no view controller for each xib file, though. 但是,每个xib文件都没有视图控制器。 (The documentation for InAppSettingsKit is sparse, so these things may not be obvious just by taking a quick look at it.) (InAppSettingsKit的文档很稀疏,所以通过快速查看它们可能并不明显。)

actually its possible to do this. 实际上它可以做到这一点。

Open your .xib file,select File's Owner(in placeholder) -> "identity inspector" (utilities) -> change class name to your controller classname -> press control and drag file's owner placeholder to View object, select "view" in dialog. 打开.xib文件,选择文件所有者(占位符) - >“身份检查器”(实用程序) - >将类名更改为控制器类名 - >按控件并将文件的所有者占位符拖动到View对象,在对话框中选择“视图” 。 Now you can customize your view. 现在您可以自定义视图。

ps you can use the same outlets as first xib, you need only to drag them to the new xib(+control sure). ps你可以使用与第一个xib相同的插座,你只需要将它们拖到新的xib(+ control sure)。

here is an explained tutorial: 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/ 这是一个解释性教程: http//irawd.wordpress.com/2013/09/05/how-to-link-a-xib-file-to-a-class-and-use-2-xib-files-换的iphone4和-的iphone5 /

Every View should have a corresponding UIViewController. 每个View都应该有一个相应的UIViewController。 Using one ViewController to "Control" more than one view breaks the MVC paradigm. 使用一个ViewController来“控制”多个视图会破坏MVC范例。 "Controlling" multiple "views" from one controller will make it much harder to change one thing without breaking something else. 从一个控制器“控制”多个“视图”将使得在不破坏其他东西的情况下更改一件事变得更加困难。 The choices you make on how to present the content to the end user will be different for every individual. 您对如何向最终用户展示内容所做的选择对于每个人来说都是不同的。 So if you say a NavigationController won't work in your case, maybe a Modal view is the answer or, you might just instantiate your custom UIViewControllers and add them to your view ([addSubview:]), if thats the road you want, but like I said, it would be beneficial for you to make a "controller" for each view object along with the corresponding xib. 因此,如果你说一个NavigationController在你的情况下不起作用,也许一个模态视图是答案,或者你可能只是实例化你的自定义UIViewControllers并将它们添加到你的视图([addSubview:]),如果那是你想要的道路,但就像我说的那样,为每个视图对象和相应的xib创建一个“控制器”将是有益的。 If you need information sent back, use a delegate or use Notifications to send the message back to the parent view. 如果需要发回的信息,请使用委托或使用通知将消息发送回父视图。 I learned the hard way that not following MVC paradigm, will make you life miserable. 我学到了不遵循MVC范式的艰难方法,会让你的生活变得悲惨。 Try and keep your code as decoupled as possible. 尝试并尽可能将代码保持分离状态。 And read up on the MVC design pattern, you won't regret it. 阅读MVC设计模式,你不会后悔的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM