【问题标题】:Difference between addChildViewController and addSubview?addChildViewController 和 addSubview 的区别?
【发布时间】:2015-08-06 23:08:48
【问题描述】:

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

【问题讨论】:

标签: ios view addsubview


【解决方案1】:

它们非常不同。 addChildViewController 将视图控制器与父容器视图控制器相关联,而 addSubview 将视图添加到要添加到的视图的视图层次结构中。在前一种情况下,新的子视图控制器将在它是其父视图控制器的选定视图控制器时负责处理事件。想想一个标签栏控制器——每个标签都有自己关联的“子”视图控制器,它在父标签栏控制器的内容区域内显示其视图,并在标签栏中选择相应的标签时处理该视图中的任何用户交互。仅当您拥有自定义容器视图并希望将新视图控制器添加到其 childViewControllers 属性时,才应使用 addChildViewController。如果您只是想在可以接收事件的视图层次结构中添加一个新视图,听起来就是这样,那么 addSubview 就是要走的路。 "Implementing a Container View Controller" section explains what addChildViewController is for.

【讨论】:

    【解决方案2】:

    适用于 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 的实例,那么您肯定必须使用@ 987654335@.

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

    【讨论】:

      【解决方案3】:

      addChildViewControllerUIViewController 类中的方法,并且 addSubview 属于 UIView

      两者的行为完全不同。

      addChildViewController 只是在当前视图控制器前面放置一个视图控制器。您必须管理控制器的流程。此方法仅供自定义容器视图控制器的实现调用。

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

      【讨论】:

        【解决方案4】:

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

        因此,请注意addChildViewController 本身对视图没有任何作用。您通常会立即使用添加其视图的调用来跟踪它,例如这是 iOS 视图控制器编程指南的 Implementing a Custom Container View 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
        

        所以,这不是addSubviewaddChildViewController 的问题,而是addSubviewaddChildViewController+addSubview 的问题。如果您调用addChildViewController,您这样做是为了在某个时候调用addSubview 以获得它的视图。

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

        有关视图控制器包含的良好介绍(例如,该 API 的基本原理、保持视图层次结构与视图控制器层次结构同步的重要性等),请参阅 WWDC 2011 视频Implementing UIViewController Containment

        【讨论】:

        • 在代码块中。我理解除了最后一行之外的所有行。似乎是多余的。你已经告诉parentViewController 它有一个childView。为什么你必须告诉childView你有一个父母?!添加子视图时,我们只需执行self.addSubView(subview)。我们不会添加额外的subview.didGerAddedToSuperView
        • 这不是多余的。它是遏制的重要组成部分。我建议你想要那个视频,它描述了你为什么需要这个。底线,willMoveToParentViewController(由addChildViewController 调用)和didMoveToParentViewController 结束进程(如viewWillAppearviewDidAppear)。
        • 哦,好吧,很好的比喻。 想要那个视频
        【解决方案5】:

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

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

        但是

        • 子视图收不到部分系统消息,如- willRotateToInterfaceOrientation:duration:

        但是,我现在不能提供消息列表。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 你的帖子更像是一个建议
          【解决方案7】:

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

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

          但是,如果您打算向 view + controller 投放广告,那么您必须使用 addChildViewController 将其 controller 和 ALSO addSubView 添加到添加它的视图。例如添加另一个视图控制器,tableViewController。

          另外:

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

          1-外观方法:

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

          2- 旋转方式:

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

          here 是您不这样做会遇到问题的示例

          如需了解更多信息,我强烈建议查看this问题的答案。

          【讨论】:

            猜你喜欢
            • 2012-06-26
            • 2010-12-03
            • 2012-04-25
            • 1970-01-01
            • 2015-11-27
            • 1970-01-01
            • 2015-07-16
            • 2011-09-12
            • 1970-01-01
            相关资源
            最近更新 更多