addChildViewController 实际上是做什么的? [英] What does addChildViewController actually do?

查看:29
本文介绍了addChildViewController 实际上是做什么的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是第一次涉足 iOS 开发,我必须做的第一件事就是实现一个 自定义容器视图控制器 - 让我们称之为 SideBarViewController - 交换它显示的几个可能的子视图控制器中的哪一个,几乎与标准的标签栏控制器一模一样.(它几乎是一个标签栏控制器,但带有一个可隐藏的侧边菜单而不是标签栏.)

I'm just dipping my feet for the first time into iOS development, and one of the first things I've had to do is implement a custom container view controller - lets call it SideBarViewController - that swaps out which of several possible child view controllers it shows, almost exactly like a standard Tab Bar Controller. (It's pretty much a Tab Bar Controller but with a hideable side menu instead of a tab bar.)

根据 Apple 文档中的说明,每当我将子 ViewController 添加到我的容器时,我都会调用 addChildViewController.我用于换出 SideBarViewController 显示的当前子视图控制器的代码如下所示:

As per the instructions in the Apple documentation, I call addChildViewController whenever I add a child ViewController to my container. My code for swapping out the current child view controller being shown by the SideBarViewController looks like this:

- (void)showViewController:(UIViewController *)newViewController {
    UIViewController* oldViewController = [self.childViewControllers 
                                           objectAtIndex:0];
    
    [oldViewController removeFromParentViewController];
    [oldViewController.view removeFromSuperview];
    
    newViewController.view.frame = CGRectMake(
        0, 0, self.view.frame.size.width, self.view.frame.size.height
    );
    [self addChildViewController: newViewController];
    [self.view addSubview: newViewController.view];
}

然后我开始试图弄清楚 addChildViewController 在这里做了什么,但我意识到我不知道.除了在 .childViewControllers 数组中粘贴新的 ViewController 之外,它似乎对任何东西都没有影响.即使我从不调用 addChildViewController,从子控制器的视图到我在情节提要上设置的子控制器的操作和出口仍然可以正常工作,而且我无法想象它还会影响什么.

Then I started trying to figure out just what addChildViewController does here, and I realised that I have no idea. Besides sticking the new ViewController in the .childViewControllers array, it seems to have no effect on anything. Actions and outlets from the child controller's view to the child controller that I've set on the storyboard still work just fine even if I never call addChildViewController, and I can't imagine what else it could affect.

事实上,如果我重写我的代码不调用addChildViewController,而是看起来像这样......

Indeed, if I rewrite my code to not call addChildViewController, and instead look like this...

- (void)showViewController:(UIViewController *)newViewController {

    // Get the current child from a member variable of `SideBarViewController`
    UIViewController* oldViewController = currentChildViewController;

    [oldViewController.view removeFromSuperview];

    newViewController.view.frame = CGRectMake(
        0, 0, self.view.frame.size.width, self.view.frame.size.height
    );
    [self.view addSubview: newViewController.view];

    currentChildViewController = newViewController;
}

...那么我的应用程序仍然可以完美运行,据我所知!

... then my app still works perfectly, so far as I can tell!

Apple 文档并没有太多说明 addChildViewController 的作用,或者我们为什么要调用它.在 的部分中对该方法的作用或为什么应该使用该方法的相关描述的全部范围UIViewController 类参考,目前是:

The Apple documentation doesn't shed much light on what addChildViewController does, or why we're supposed to call it. The entire extent of the relevant description of what the method does or why it should be used in its section in the UIViewController Class Reference is, at present:

将给定的视图控制器添加为子级....此方法仅旨在由自定义容器视图控制器的实现调用.如果您覆盖此方法,则必须在您的实现中调用 super.

Adds the given view controller as a child. ... This method is only intended to be called by an implementation of a custom container view controller. If you override this method, you must call super in your implementation.

在同一页的前面还有这一段:

There's also this paragraph earlier on the same page:

在将子视图的根视图添加到视图层次结构之前,您的容器视图控制器必须将子视图控制器与其自身相关联.这允许 iOS 正确地将事件路由到子视图控制器和这些控制器管理的视图.同样,在从其视图层次结构中删除子视图的根视图后,它应该断开该子视图控制器与其自身的连接.为了建立或打破这些关联,您的容器调用由基类定义的特定方法.这些方法不打算由容器类的客户端调用;它们只能由您的容器实现使用,以提供预期的遏制行为.

Your container view controller must associate a child view controller with itself before adding the child’s root view to the view hierarchy. This allows iOS to properly route events to child view controllers and the views those controllers manage. Likewise, after it removes a child’s root view from its view hierarchy, it should disconnect that child view controller from itself. To make or break these associations, your container calls specific methods defined by the base class. These methods are not intended to be called by clients of your container class; they are to be used only by your container’s implementation to provide the expected containment behavior.

以下是您可能需要调用的基本方法:

Here are the essential methods you might need to call:

addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:

addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:

但它没有提供关于它所谈论的事件"或预期的收容行为"是什么,或者为什么(甚至何时)调用这些方法是必不可少的"的任何线索.

but it doesn't offer any clue as to what the 'events' or 'expected containment behavior' that it's talking about are, or why (or even when) calling these methods is 'essential'.

自定义容器视图控制器"中的自定义容器视图控制器示例Apple 文档的一部分都调用了这个方法,所以我认为它除了将子 ViewController 弹出到数组之外还有一些重要的用途,但我不知道这个目的是什么.这个方法有什么作用,为什么要调用它?

The examples of custom container view controllers in the "Custom Container View Controllers" section of the Apple documentation all call this method, so I assume that it serves some important purpose beyond just popping the child ViewController onto an array, but I can't figure out what that purpose is. What does this method do, and why should I call it?

推荐答案

我也想知道这个问题.我观看了WWDC 2011 的第 102 场会议视频和查看控制器先生,Bruce D. Nilo 说:

I was wondering about this question too. I watched Session 102 of the WWDC 2011 videos and Mr. View Controller, Bruce D. Nilo, said this:

viewWillAppear:viewDidAppear: 等与 addChildViewController: 无关.addChildViewController: 所做的只是说这个视图控制器是那个视图控制器的一个孩子",它与视图外观无关.调用它们的时间与视图移入和移出窗口层次结构的时间相关联.

viewWillAppear:, viewDidAppear:, etc have nothing to do with addChildViewController:. All that addChildViewController: does is to say "This view controller is a child of that one" and it has nothing to do with view appearance. When they get called is associated with when views move in and out of the window hierarchy.

所以对 addChildViewController: 的调用似乎做的很少.调用的副作用是重要的部分.它们来自 parentViewControllerchildViewControllers 关系.以下是我所知道的一些副作用:

So it seems that the call to addChildViewController: does very little. The side effects of the call are the important part. They come from the parentViewController and childViewControllers relationships. Here are some of the side effects that I know:

  • 将外观方法转发给子视图控制器
  • 转发轮换方法
  • (可能)转发内存警告
  • 避免不一致的 VC 层次结构,尤其是在 transitionFromViewController:toViewController:... 中,其中两个 VC 都需要具有相同的父级
  • 允许自定义容器视图控制器参与状态保存和恢复
  • 参与响应链
  • 连接navigationControllertabBarController等属性
  • Forwarding appearance methods to child view controllers
  • Forwarding rotation methods
  • (Possibly) forwarding memory warnings
  • Avoiding inconsistent VC hierarchies, especially in transitionFromViewController:toViewController:… where both VCs need to have the same parent
  • Allowing custom container view controllers to take part in State Preservation and Restoration
  • Taking part in the responder chain
  • Hooking up the navigationController, tabBarController, etc properties

这篇关于addChildViewController 实际上是做什么的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆