添加为subView时,未调用UIViewController viewWillAppear

Fog*_*ter 25 objective-c uiscrollview uiviewcontroller viewwillappear ios

我有一个UIViewController我从另一个视图控制器内部加载,然后将其视图添加到UIScrollView.

self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;

[self.scrollView addSubview:self.statisticsController.view];
Run Code Online (Sandbox Code Playgroud)

我已经在统计视图控制器中放置断点并且viewDidLoad正在调用但viewWillAppear不是.

是因为我没有把它推到层次结构上还是什么?

rde*_*mar 45

您应该添加statisticsController为控制器的子视图控制器,其视图是您要添加的.

self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;

[self.scrollView addSubview:self.statisticsController.view];
[self addChildViewController:self.statisticsController];
[self.statisticsController didMoveToParentViewController:self];
Run Code Online (Sandbox Code Playgroud)

我不确定这会viewDidAppear被调用,但是你可以didMoveToParentViewController:在子控制器中覆盖,并且会调用它,所以你可以放入任何你应该放入的代码viewDidAppear.

  • 实际上你必须首先`addChildViewController`,然后`addSubview`. (8认同)

Aec*_*Liu 41

-viewWillAppear:再次遇到没有被问到的问题.谷歌搜索后,我来到这里.我做了一些测试,并发现调用顺序-addSubview-addChildViewController:重要性.

案例1.将触发-viewWillAppear:控制器,但案例2,不会调用-viewWillAppear:.

情况1:

  controller?.willMoveToParentViewController(self)

  // Call addSubview first
  self.scrollView.addSubview(controller!.view)
  self.addChildViewController(controller!)

  controller!.didMoveToParentViewController(self)
Run Code Online (Sandbox Code Playgroud)

案例2:

  controller?.willMoveToParentViewController(self)

  // Call adChildViewController first      
  self.addChildViewController(controller!)      
  self.scrollView.addSubview(controller!.view)

  controller!.didMoveToParentViewController(self)
Run Code Online (Sandbox Code Playgroud)

  • 有趣.这与视图控制器编程指南中Apple的文档相矛盾.你应该提交一个bug. (6认同)
  • 我可以补充一点,这个错误在 iOS 10 上发生在我们身上。后来在 iOS 11 上工作得很好。 (2认同)

Ale*_*nov 18

默认情况下,外观回调会自动转发给子级.它是由shouldAutomaticallyForwardAppearanceMethods属性决定的.检查这个属性的值,如果它是NO并且你的子viewController应该出现在容器的外观上,你应该在容器的控制器生命周期实现中用以下方法通知child:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    for (UIViewController *child in self.childViewControllers) {
        [child beginAppearanceTransition:YES animated:animated];
    }
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.child endAppearanceTransition];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    for (UIViewController *child in self.childViewControllers) {
        [child beginAppearanceTransition:NO animated:animated];
    }
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [self.child endAppearanceTransition];
}
Run Code Online (Sandbox Code Playgroud)

自定义外观和旋转回调行为

解决了我的问题!希望它会有所帮助.


bom*_*mpf 5

正如另一个答案中提到的,父视图控制器viewWillAppearshouldAutomaticallyForwardAppearanceMethods设置为时可能不会调用等falseUINavigationController并且UITabBarController众所周知这样做。在这种情况下,您需要在视图出现时beginAppearanceTransition(_ isAppearing: Bool, animated: Bool)使用isAppearingset调用子视图控制器,true反之亦然。

您必须在代码中的适当位置放置这些调用,通常是在添加和删除子视图控制器时。

不要忘了打电话endAppearanceTransition时,您的自定义转换已经结束,否则你的孩子视图控制器上viewDidAppear,并viewDidDisappear没有叫。