addChildViewController和addSubview之间的区别?

这两种方法都将视图添加为父视图的视图,视图可以接收事件 。 什么时候使用哪一个?

他们是非常不同的。 addChildViewController将视图控制器与父容器视图控制器相关联,而addSubview将视图添加到要添加到的视图的视图层次结构中。 在前一种情况下,新的子视图控制器将负责处理它的父节点的选定视图控制器时的事件。 考虑一个标签栏控制器 – 每个标签都有自己的关联“子”视图控制器,在父标签栏控制器的内容区域中显示其视图,并在标签栏中选择相应的标签时处理该视图中的任何用户交互。 只有拥有自定义容器视图并且想要将新视图控制器添加到其childViewControllers属性时,才应使用addChildViewController。 如果您只想将新视图添加到可以接收事件的视图层次结构中,这听起来就像是这样,addSubview是可行的方法。 “实现容器视图控制器”部分解释了addChildViewController的用途。

这一切都取决于您希望如何管理新的子视图。 如果您希望新的子视图由当前视图的视图控制器管理(例如,您正在添加一些简单的东西,比如几个UILabel对象),您只需调用addSubview 。 另一方面,如果新的子视图有自己的视图控制器(即它是足够复杂的视图集合,具有丰富的function,您希望用自己的控制器封装所有这些复杂性来管理这个新子视图所做的一切)然后你调用addChildViewController来添加新的视图控制器,但是也调用addSubview

所以,请注意addChildViewController本身对视图没有任何作用。 您通常会立即使用添加其视图的调用来跟踪它,例如,这是来自适用于iOSView Controller编程指南的实现自定义容器视图控制器部分的一个略微阐明的示例

 [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

坦率地说, addSubviewaddChildViewController + addSubview这个问题我们很少考虑这个问题。 更合乎逻辑的思考方式是确定这个新视图是否有自己的视图控制器。 如果是,则执行addChildViewController调用序列。 如果没有,您只需调用addSubview

有关视图控制器包含的详细介绍(例如,该API的基本原理,保持视图层次结构与视图控制器层次结构同步的重要性等),请参阅WWDC 2011video实现UIViewController包含 。

addChildViewControllerUIViewController类中的方法, addSubviewUIView类中的方法

两者都有完全不同的行为。

addChildViewController只是将视图控制器放在当前视图控制器的前面。 您必须管理控制器的流程。 此方法仅用于通过自定义容器视图控制器的实现来调用。

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

知道MVC意味着模型 – 视图 – 控制器:

如果您只想添加视图 ,请使用addSubview 。 例如,添加标签,按钮。

但是,如果您打算广告查看 + 控制器,则必须使用addChildViewController添加其控制器,并使用addSubView添加其视图 。 例如,添加另一个viewController,tableViewController。

此外:

转发到子视图控制器的事件有两类:

1-外观方法:

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

2-轮换方法:

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

有关详细信息,我强烈建议您查看有关此问题的答案。

可从iOS 5, addChildViewController:

 - (void)addChildViewController:(UIViewController *)childController NS_AVAILABLE_IOS(5_0); 

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

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

另一方面

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

addSubview:将任何视图添加为任何其他视图的subview视图。

当它要求使用特定方法的类型时, 它不是选择使用的。

例如 –

如果你有一个UIViewController的实例,你肯定会使用addChildViewController:你也可以使用presentModalViewControllerpushViewController ),如果你有一个UIView实例,你必须使用addSubview

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

根据一些测试,我发现:如果没有将子视图控制器添加到父视图控制器(假设父视图控制器位于根视图控制器下),则只有子视图控制器的视图被添加到父视图控制器的视图中,然后:

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

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

但是,我现在无法给出消息列表。

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