简体   繁体   English

是否可以将UIViewController的视图添加到另一个UIViewController的视图中?

[英]Is it advisable to add a UIViewController's view to another UIViewController's view?

Is it advisable to add a UIViewController 's view to another UIViewController 's view ? 是否可以将UIViewControllerview添加到另一个UIViewControllerview

Please explain why it is a good practice or a bad practice. 请解释为什么这是一个好的做法或一个不好的做法。

Apple and thus most people following Apple's guidelines will tell you it's bad practice and that Apple added ViewController containment (childViewControllers) for that reason. 苹果公司以及大多数遵循Apple指南的人都会告诉你这是不好的做法,因此Apple添加了ViewController包含(childViewControllers)。 Unfortunately, most people blindly follow that and won't tell you why it is bad practice. 不幸的是,大多数人盲目地遵循这一点,并不会告诉你为什么这是不好的做法。 And I'm glad that you do ask that. 而且我很高兴你这么做。

The truth is, in a model-view-controller architecture, views should be reuseable regardless of the content they contain, thus the view and the object controlling the view's content should not be the same. 事实上,在模型 - 视图 - 控制器体系结构中,视图应该是可重用的,无论它们包含什么内容,因此视图和控制视图内容的对象不应该相同。 Which is exactly what a UIViewController does yet prior to iOS5 Apple discouraged you to use them in multiples while it's a very logical thing to do. 这正是UIViewController在iOS5之前所做的事情Apple不鼓励你多次使用它们,而这是非常合乎逻辑的事情。 Ofcourse this was confusing, many people ignored the guidelines and did it anyway, myself included, apps worked fine and passed app store validation which caused even more confusion. 当然这很令人困惑,许多人忽略了指导方针,无论如何都做了,包括我自己,应用程序工作正常并通过了应用商店验证,这引起了更多的混乱。 The result is that to this day people still ask questions about this even more than a year after Apple caved and gave us custom container ViewControllers. 结果是,直到今天,人们仍然在Apple塌陷并给我们自定义容器ViewControllers一年多后就此问题。 I've seen people respond to this question often with complex answers as far as recreating UIViewController as a class that inherits from NSObject for very simple issues. 我已经看到人们经常使用复杂的答案来回答这个问题,只要将UIViewController重新创建为一个继承自NSObject的类来解决非常简单的问题。 Just because Apple discourages using UIViewControllers and without even knowing why. 仅仅因为Apple不鼓励使用UIViewControllers,甚至不知道为什么。

Since adding a ViewController's view as a subview will often work perfectly and ViewController containment is not available in iOS4 which many still support, too many people don't bother using ViewController containment. 由于将ViewController的视图添加为子视图通常可以很好地工作,并且iOS4中仍然没有ViewController包含,许多人仍然支持,太多人不打扰使用ViewController包含。 It is the cleaner solution and when you feel like using ViewControllers in ViewControllers, you should use it when possible. 这是更清洁的解决方案,当您想在ViewControllers中使用ViewControllers时,您应该尽可能使用它。 If not, in most situations you should be able to simply add a ViewController's view as a subview, you just have to know in which situations. 如果没有,在大多数情况下,您应该能够简单地将ViewController的视图添加为子视图,您只需知道在哪些情况下。

Here's what you can expect if you just add a ViewController's view to another view: 如果您只是将ViewController的视图添加到另一个视图,那么您可以期待以下内容:

  • View callback methods are not guaranteed to get called. 查看回调方法不能保证被调用。 Methods like viewWillAppear, viewDidAppear, viewWillDisappear and viewDidDisappear may or may not get called. viewWillAppear,viewDidAppear,viewWillDisappear和viewDidDisappear等方法可能会被调用,也可能不会被调用。 It will largely depend on the OS version, in iOS4 they won't ever get called, in iOS5 and above they'll mostly get called. 它在很大程度上取决于操作系统版本,在iOS4中它们永远不会被调用,在iOS5及以上版本中,它们通常会被调用。 So you can't override these methods because you can't rely on them, you have no control over when, if or how many times they'll get called. 所以你不能覆盖这些方法,因为你不能依赖它们,你无法控制它们被调用的时间,次数或次数。
  • The only view callback method that will always get called correctly is viewDidLoad. 始终被正确调用的唯一视图回调方法是viewDidLoad。
  • Rotation callbacks won't get called. 旋转回调不会被调用。 Depending on your situation this may be a big deal or not matter at all. 根据您的情况,这可能是一个大问题或根本不重要。 If the view's autoresizingmask is enough to reposition and rescale it then you're fine. 如果视图的autoresizingmask足以重新定位并重新缩放它,那么你就没事了。 If not, you can always do a custom implementation when the superview's ViewController's rotation callbacks get called. 如果没有,您可以在调用superview的ViewController的旋转回调时始终执行自定义实现。
  • You have to keep a reference to the ViewController yourself, otherwise it'll get released immediately while its view will still be retained by its superview. 您必须自己保留对ViewController的引用,否则它将立即释放,而其视图仍将由其superview保留。

I definitely wouldn't encourage it but I don't discourage it either. 我绝对不会鼓励它,但我也不会劝阻它。 It's situational and if you don't have to support iOS4 anymore then you can mostly avoid it. 这是情境化的,如果你不再需要支持iOS4那么你可以避免它。 But if you keep the above list in mind then it won't cause any harm either and your app will work fine. 但是,如果你记住上面的列表,那么它也不会造成任何伤害,你的应用程序将正常工作。

Sometimes it's ok, and sometimes it's not. 有时它没关系,有时它不是。 It's hard to give a better answer than that without showing some diagrams and explaining the relationship between the view controller hierarchy and the view hierarchy. 如果没有显示一些图表并解释视图控制器层次结构和视图层次结构之间的关系,那么很难给出更好的答案。

Fortunately, Apple has already done that. 幸运的是,Apple已经做到了。 Watch the “Implementing UIViewController Containment” video from WWDC 2011 for a detailed explanation of when it's ok and when it's not. 观看WWDC 2011中的“实现UIViewController遏制”视频,详细说明何时可以,何时不可以。

This is actually a common situation with complex view hierarchies. 这实际上是复杂视图层次结构的常见情况。 Since iOS 5, UIViewController enables you to add a child view controller. 从iOS 5开始, UIViewController允许您添加子视图控制器。 When you are adding the child controller, you are also adding the child's view into the controller's view. 添加子控制器时,还要将子视图添加到控制器的视图中。

On the other hand, you should never add a view controller's view to another view controller without adding it as the child view controller. 另一方面,您永远不应将视图控制器的视图添加到另一个视图控制器,而不将其添加为子视图控制器。

However, don't abuse it. 但是,不要滥用它。 You should do it when 你应该这样做

  • you are implementing a container for a set of controllers (something like your own UINavigationController or UISplitViewController ) 您正在为一组控制器实现容器(类似于您自己的UINavigationControllerUISplitViewController
  • the child controller is independent. 子控制器是独立的。 If the child controllers constantly call methods on its parent and viceversa, it would be a better idea to implement the functionality into one controller. 如果子控制器不断地在其父控制器上调用方法,那么将功能实现到一个控制器中会更好。

You might get away with it but there is probably a better way. 你可能会逃脱它,但可能有更好的方法。 It seems reasonable to think that both will attempt to manipulate the view. 认为两者都试图操纵视图似乎是合理的。 My answer is no. 我的回答是否定的。

What are you trying to accomplish? 你想达到什么目的?

Of course you can add UIViewController's view to another UiViewController's view at least as a class variable. 当然,您可以将UIViewController的视图添加到另一个UiViewController的视图中,至少作为类变量。 But I can't understand the final goal of this solution. 但我无法理解这个解决方案的最终目标。 I think it is a bad practice because of the app interface complexity is increasing. 我认为这是一个不好的做法,因为应用程序界面的复杂性正在增加。

Usually in Model-View-Controller architecture, we can reuse views. 通常在模型 - 视图 - 控制器架构中,我们可以重用视图。

But for the UIViewController, it may be not be always good idea. 但是对于UIViewController,它可能并不总是好主意。 It might make the project architecture complex because as per Apple documentation views are tightly bound to view-controller, so it may not be easily manageable. 它可能会使项目架构变得复杂,因为根据Apple文档视图与视图控制器紧密绑定,因此它可能不容易管理。

From UIViewController reference: View controllers are tightly bound to the views they manage and take part in the responder chain used to handle events. 从UIViewController引用:视图控制器与它们管理的视图紧密绑定,并参与用于处理事件的响应器链。 View controllers are descendants of the UIResponder class and are inserted into the responder chain between the managed root view and its superview, which typically belongs to a different view controller. 视图控制器是UIResponder类的后代,并插入到托管根视图与其超级视图之间的响应程序链中,后者通常属于不同的视图控制器。 If the view controller's view does not handle an event, the view controller has the option of handling the event or it can pass the event to the superview. 如果视图控制器的视图不处理事件,则视图控制器可以选择处理事件,也可以将事件传递给superview。

But, I think we can reuse a view if there is minor difference in the UI for the two different controllers. 但是,我认为如果两个不同控制器的UI存在细微差别,我们可以重用视图。

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

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