addChildViewController和addSubview的区别是什么?

18

这两种方法都将视图添加为< strong>父视图的子代,视图可以接收< strong>事件。何时使用哪个方法?


嗨,请参考以下链接。https://dev59.com/zGgu5IYBdhLWcg3wpYYj - VD Patel
1
以下是一些好的答案 -> https://dev59.com/zGQm5IYBdhLWcg3w-i9L - Yevgeniy Leychenko
1
addchildviewcontroller适用于ViewControllers(将其作为主视图控制器的子控制器添加到containerViewControllers中),而另一个适用于视图上的addSubview(在父视图上添加子视图)。它们的基本区别在于ViewController和UIView上。阅读此https://dev59.com/zGQm5IYBdhLWcg3w-i9L - Jen Jose
7个回答

27
这完全取决于你想如何管理新的子视图。如果你希望当前视图控制器管理新的子视图(例如,你只是添加一些简单的UILabel对象),则只需调用addSubview。另一方面,如果新的子视图有自己的视图控制器(即它是一个包含复杂集合视图和丰富功能的足够复杂的子视图,你希望使用自己的控制器来封装所有这些复杂性以管理该新子视图所做的一切),那么你需要调用addChildViewController来添加新的视图控制器,但也要调用addSubview
因此,请注意,addChildViewController本身不对视图进行任何操作。通常,你会立即跟随它并调用其视图,例如,在iOS的View Controller Programming Guide实现自定义容器视图控制器部分中有一个稍微澄清的示例。
[self addChildViewController:childViewController];        // add subview's view controller
childViewController.view.frame = ...                      // specify where you want the new subview
[self.view addSubview:childViewController.view];          // now you can add the child view controller's view
[childViewController didMoveToParentViewController:self]; // now tell the child view controller that the adding of it and its views is all done

因此,问题不在于 addSubview vs addChildViewController,而是 addSubview vs addChildViewController+addSubview。如果您调用 addChildViewController,则意味着您打算随时调用其视图的 addSubview
坦白地说,我们很少这样考虑 addSubview vs. addChildViewController+addSubview 的问题。更合理的思考方式是确定这个新视图是否有自己的视图控制器。如果有,您就执行 addChildViewController 的一系列调用。如果没有,您只需调用 addSubview
有关视图控制器容器的良好介绍(例如该 API 的基本原理、保持视图层次结构与视图控制器层次结构同步的重要性等),请参见 WWDC 2011 视频 Implementing UIViewController Containment

在代码块中,除了最后一行,我理解所有的代码。它似乎是多余的。您已经告诉parentViewController它有一个子视图。为什么还要告诉子视图您有一个父视图?当添加子视图时,我们只需执行self.addSubView(subview)。我们不需要添加额外的subview.didGerAddedToSuperView - mfaani
1
这并不是冗余的,而是包含过程中必不可少的部分。我建议你观看那个视频,它会说明为什么需要这个过程。总之,willMoveToParentViewController(由addChildViewController调用)和didMoveToParentViewController(就像viewWillAppearviewDidAppear)把整个过程框起来。 - Rob
哦,好的,很好的比喻。想看那个视频 <-- 你是什么意思?什么视频? - mfaani

12
它们非常不同。addChildViewController将一个视图控制器与父容器视图控制器关联起来,而addSubview则将一个视图添加到要添加到的视图的视图层次结构中。在前者的情况下,新的子视图控制器将负责处理其父控制器选择它时的事件。想象一下标签栏控制器-每个选项卡都有其自己的相关“子”视图控制器,该视图控制器在父标签栏控制器的内容区域内显示其视图,并处理对应选项卡在标签栏中被选中时出现的任何用户交互。仅当您拥有自定义容器视图并希望将新的视图控制器添加到其childViewControllers属性中时,才应使用addChildViewController。如果您只想添加一个新的视图到视图层次结构中,使其能够接收事件(这听起来就像是),那么addSubview就是正确的方法。 "实现容器视图控制器"部分解释了addChildViewController的用途。

3

addChildViewController 是 UIViewController 类中的一个方法,而 addSubview 则是 UIView 类中的一个方法。

它们的行为完全不同。

addChildViewController 只是将一个视图控制器放在当前视图控制器的前面。您需要管理控制器的流程。此方法仅应由自定义容器视图控制器的实现调用。

addSubview 将另一个视图添加为该对象的子视图。


2

了解MVC的意思是指模型-视图-控制器:

如果您只想添加视图,则使用addSubview命令。例如:添加标签、按钮等。

但是,如果您想要添加视图+控制器,那么您必须使用addChildViewController来添加其控制器并且同时使用addSubView来添加其视图。例如:添加另一个视图控制器、表格视图控制器等。

此外:

有两类事件会转发给子视图控制器:

1- 外观方法:

- viewWillAppear:
- viewDidAppear:
- viewWillDisappear:
- viewDidDisappear:

2-旋转方法:

- willRotateToInterfaceOrientation:duration:
- willAnimateRotationToInterfaceOrientation:duration:
- didRotateFromInterfaceOrientation:

如果您不这样做,可能会遇到问题的一个例子在这里
想要了解更多信息,我强烈建议查看这个问题上的答案。

1

根据一些测试,我发现:如果子视图控制器没有添加到父视图控制器(假设父视图控制器在根视图控制器下面),则只有子视图控制器的视图被添加到父视图控制器的视图中,那么:

  • 子视图控制器仍然可以直接接收与视图相关的消息,例如 - viewWillAppear:- viewWillLayoutSubviews等。

但是

  • 子视图无法接收某些系统消息,例如 - willRotateToInterfaceOrientation:duration:

我现在无法提供消息列表。


1
从iOS 5开始可用,addChildViewController:方法。
- (void)addChildViewController:(UIViewController *)childController NS_AVAILABLE_IOS(5_0);

方法让您将任何视图控制器作为子控制器添加到其他视图控制器中,但首先它会从childController中删除任何父级,然后将其作为子视图控制器添加到指定的控制器中。

子控制器只是UIViewController的一个实例,因此它将提供视图控制器的功能(例如,它将像普通的UIViewController一样接收事件,如-(void)viewWillAppear-(void)viewWillDisappear等)。

另一方面

 - (void)addSubview:(UIView *)view;

addSubview:会将任何视图作为subview添加到其他视图上。

选择使用哪个方法并不重要,而是根据类型来决定使用特定的方法。

例如 -

如果您有一个UIViewController的实例,那么您肯定会使用addChildViewController:(也可以使用presentModalViewControllerpushViewController),如果您有一个UIView的实例,则绝对必须使用addSubview

注意:您还可以将视图控制器的视图添加为其他视图的子视图。


0

addChildViewController 用于防止添加的子视图控制器释放,换句话说,父视图控制器将持有子视图控制器的强引用。


你的帖子更像是一个建议。 - Raju

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接