将 UIViewController 的视图添加到另一个 UIViewController 的视图是否明智?

发布于 2025-01-08 07:14:37 字数 151 浏览 2 评论 0原文

UIViewControllerview 添加到另一个 UIViewControllerview 是否明智?

请解释为什么这是一个好的做法或不好的做法。

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

Please explain why it is a good practice or a bad practice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

不必了 2025-01-15 07:14:38

Apple 以及遵循 Apple 指南的大多数人都会告诉您这是不好的做法,并且 Apple 出于这个原因添加了 ViewController 包含(childViewControllers)。不幸的是,大多数人盲目地遵循这一点,并且不会告诉你为什么这是不好的做法。我很高兴你这么问。

事实是,在模型-视图-控制器架构中,视图应该是可重用的,无论它们包含什么内容,因此视图和控制视图内容的对象不应该是相同的。这正是 UIViewController 所做的事情,但在 iOS5 之前,Apple 不鼓励您多次使用它们,尽管这是一个非常合乎逻辑的事情。当然,这很令人困惑,许多人忽略了指南并无论如何都这样做了,包括我自己,应用程序运行良好并通过了应用程序商店验证,这导致了更多混乱。
结果是,直到今天,即使在苹果屈服并为我们提供自定义容器 ViewController 一年多之后,人们仍然会问这个问题。我看到人们经常用复杂的答案来回答这个问题,甚至将 UIViewController 重新创建为一个继承自 NSObject 的类来解决非常简单的问题。只是因为苹果不鼓励使用 UIViewControllers 并且甚至不知道为什么。

由于将 ViewController 的视图添加为子视图通常会完美地工作,并且 ViewController 包含在 iOS4 中不可用(许多人仍然支持),所以太多人不费心使用 ViewController 包含。这是更干净的解决方案,当您想在 ViewController 中使用 ViewController 时,应该尽可能使用它。如果没有,在大多数情况下,您应该能够简单地将 ViewController 的视图添加为子视图,您只需要知道在哪些情况下即可。

如果您只是将 ViewController 的视图添加到另一个视图,则可能会出现以下情况:

  • 不保证调用视图回调方法。 viewWillAppear、viewDidAppear、viewWillDisappear 和 viewDidDisappear 等方法可能会也可能不会被调用。这很大程度上取决于操作系统版本,在 iOS4 中它们永远不会被调用,在 iOS5 及更高版本中它们大多会被调用。所以你不能重写这些方法,因为你不能依赖它们,你无法控制它们何时、是否或多少次被调用。
  • 唯一始终能正确调用的视图回调方法是 viewDidLoad。
  • 旋转回调不会被调用。根据您的情况,这可能是一件大事,也可能根本不重要。如果视图的自动调整大小蒙版足以重新定位和重新缩放它,那么就可以了。如果没有,您始终可以在调用超级视图的 ViewController 的旋转回调时执行自定义实现。
  • 您必须自己保留对 ViewController 的引用,否则它将立即被释放,而其视图仍将由其超级视图保留。

我绝对不会鼓励它,但我也不阻止它。这是视情况而定的,如果您不再需要支持 iOS4,那么您基本上可以避免它。但如果您牢记上面的列表,那么它也不会造成任何损害,并且您的应用程序将正常工作。

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. 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. 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. 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. Just because Apple discourages using UIViewControllers and without even knowing why.

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. It is the cleaner solution and when you feel like using ViewControllers in ViewControllers, you should use it when possible. 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.

Here's what you can expect if you just add a ViewController's view to another view:

  • View callback methods are not guaranteed to get called. Methods like viewWillAppear, viewDidAppear, viewWillDisappear and viewDidDisappear may or may not get called. 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. 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.
  • 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. If not, you can always do a custom implementation when the superview's ViewController's rotation callbacks get called.
  • 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.

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. But if you keep the above list in mind then it won't cause any harm either and your app will work fine.

臻嫒无言 2025-01-15 07:14:38

有时可以,有时则不行。如果不显示一些图表并解释视图控制器层次结构和视图层次结构之间的关系,很难给出比这更好的答案。

幸运的是,苹果已经做到了这一点。观看 WWDC 2011 中的“实施 UIViewController 遏制”视频,了解何时实施 UIViewController 遏制的详细说明好的,什么时候不行。

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. Watch the “Implementing UIViewController Containment” video from WWDC 2011 for a detailed explanation of when it's ok and when it's not.

嘿嘿嘿 2025-01-15 07:14:38

这实际上是复杂视图层次结构的常见情况。从 iOS 5 开始,UIViewController 允许您添加子视图控制器。当您添加子控制器时,您还将子视图添加到控制器的视图中。

另一方面,您永远不应该将视图控制器的视图添加到另一个视图控制器而不将其添加为子视图控制器。

但是,不要滥用它。 时,您应该这样做,

  • 当您为一组控制器(例如您自己的 UINavigationControllerUISplitViewController)实现容器
  • 子控制器是独立的。如果子控制器不断调用其父控制器的方法,反之亦然,则最好将功能实现到一个控制器中。

This is actually a common situation with complex view hierarchies. Since iOS 5, UIViewController enables you to add a child view controller. 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)
  • 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.
尘世孤行 2025-01-15 07:14:38

您可能会侥幸逃脱,但可能有更好的方法。认为两者都会试图操纵视图似乎是合理的。我的答案是否定的。

你想实现什么目标?

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?

耳钉梦 2025-01-15 07:14:38

当然,您可以将 UIViewController 的视图至少作为类变量添加到另一个 UiViewController 的视图中。但我无法理解这个解决方案的最终目标。
我认为这是一个不好的做法,因为应用程序界面的复杂性正在增加。

Of course you can add UIViewController's view to another UiViewController's view at least as a class variable. 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.

心是晴朗的。 2025-01-15 07:14:38

通常在模型-视图-控制器架构中,我们可以重用视图。

但对于 UIViewController 来说,这可能并不总是好主意。它可能会使项目架构变得复杂,因为根据 Apple 文档,视图与视图控制器紧密绑定,因此可能不容易管理。

来自 UIViewController 参考:
视图控制器与它们管理的视图紧密绑定,并参与用于处理事件的响应者链。视图控制器是 UIResponder 类的后代,并插入到托管根视图及其超级视图之间的响应程序链中,该超级视图通常属于不同的视图控制器。如果视图控制器的视图不处理事件,则视图控制器可以选择处理该事件,或者可以将事件传递给超级视图。

但是,我认为如果两个不同控制器的 UI 存在细微差别,我们可以重用视图。

Usually in Model-View-Controller architecture, we can reuse views.

But for the UIViewController, it may be not be always good idea. 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.

From UIViewController reference:
View controllers are tightly bound to the views they manage and take part in the responder chain used to handle events. 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. 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.

But, I think we can reuse a view if there is minor difference in the UI for the two different controllers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文