如何正确实现View Controller Containers?

时间:2015-12-04 01:18:44

标签: ios uiviewcontroller uikit

我已经实现了很多视图控制器容器,但完全正确地完成生命周期仍然很棘手。

添加子视图控制器的一般方法看起来很简单:

  1. 致电parent.addChildViewController(child)(一次!)
  2. 致电child.beginAppearanceTransition(true, animated: …)(可能多次,在truefalse之间轮流展开)
  3. 将孩子的view添加到父级的视图层次结构中
  4. 布置孩子的view
  5. 致电child.endAppearanceTransition()(一次!)
  6. 致电child.didMoveToParentViewController(parent)(一次!)
  7. 现在很少这么简单。例如,父视图控制器本身可能处于转换(viewWillAppear())中,因此必须延迟步骤5和6,直到父级也完成它的转换(viewDidAppear())。

    情况可能更复杂。你可能不小心忘了打电话。或者孩子忘记拨打super.…()。或者你多次调用一个方法,你不应该再次调用它。(

    为了找到这样的bug,我在我的库中调用UIViewController中的所有生命周期方法,以便它在日志中自动报告大量不同的生命周期错误。这就像一个魅力,我在自己的容器中发现了几个问题。但是我也收到了UIKit自己的视图控制器的几个报告,所以我现在质疑我是否真的了解预期的生命周期。

    UIViewController.didMoveToParentViewController()的文档例如:

      

    如果要实现自己的容器视图控制器,则必须   调用子视图的didMoveToParentViewController:方法   转换到新控制器后的控制器完成或,   如果没有过渡,请立即拨打电话   addChildViewController:方法。

    所以现在对我来说最重要的问题是:

    方法willMoveToParentViewController()didMoveToParentViewController()是否与view(Did|Will)(Appear|Disappear)直接相关? 即如上面的文档摘录所述,在子视图控制器的转换完成之前,我不能调用didMoveToParentViewController()。这意味着必须最后调用viewDidDisappear()viewDidAppear() - viewWillAppear()viewWillDisappear()

    UIKit似乎就是这样做的(在转换期间调用(will|did)MoveToParentViewController),例如在iPhone上以模仿方式呈现UISplitViewController UINavigationController个孩子的时候:

    VIEW CONTROLLER LIFECYCLE BROKEN for <UINavigationController: 0x7cc18a00>
    
    Problem:
        .willMoveToParentViewController() was called unexpectedly during an appearance transition. It must only be called while the view controller is in DidDisappear or DidAppear state.
    
    Possible Causes:
        - the view controller containment implementation of UISplitViewController or one if its parents is broken
    
    
    
    VIEW CONTROLLER LIFECYCLE BROKEN for <UINavigationController: 0x7cc18a00>
    
    Problem:
        .didMoveToParentViewController() was called unexpectedly during an appearance transition. It must only be called while the view controller is in DidDisappear or DidAppear state.
    
    Possible Causes:
        - the view controller containment implementation of the parent view controller or one if its parents is broken
    

    当呈现具有文本字段的UIAlertViewController时,错误堆积起来:

    VIEW CONTROLLER LIFECYCLE BROKEN for <_UIAlertControllerTextFieldViewController: 0x7dd84bb0>
    
    Problem:
        .willMoveToParentViewController() was called unexpectedly while view controller is in WillMoveToParent state.
    
    Possible Causes:
        - _UIAlertControllerTextFieldViewController or one of its superclasses called super.willMoveToParentViewController() multiple times
        - _UIAlertControllerTextFieldViewController or one of its superclasses called super.willMoveToParentViewController() from within it's .didMoveToParentViewController()
        - the view controller containment implementation of UIAlertController or one if its parents is broken
        - it was already called implicitly by parent.addChildViewController(_UIAlertControllerTextFieldViewController) so you must not call it again
    
    
    
    VIEW CONTROLLER LIFECYCLE BROKEN for <UICompatibilityInputViewController: 0x7a99fdb0>
    
    Problem:
        .didMoveToParentViewController(non-nil) was not called after .viewDidAppear() to complete an earlier .willMoveToParentViewController(non-nil).
    
    Possible Causes:
        - the view controller containment implementation of UIInputWindowController is likely broken
    
    
    
    VIEW CONTROLLER LIFECYCLE BROKEN for <UICompatibilityInputViewController: 0x7dd67650>
    
    Problem:
        .didMoveToParentViewController(non-nil) was not called after .viewDidAppear() to complete an earlier .willMoveToParentViewController(non-nil).
    
    Possible Causes:
        - the view controller containment implementation of UICompatibilityInputViewController is likely broken
    

    是否有人对如何进行视图控制器遏制有很好的了解?
    这些只是UIKit中的错误还是这种行为&#34;可以接受&#34;?

    如果有人对生命周期验证和&amp;错误报告工作可以查看this file

0 个答案:

没有答案