UIViewController viewWillAppear作为子视图添加时不会调用

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

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

我已经把统计视图控制器中的断点,并调用viewDidLoadviewWillAppear不是。

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

您应该将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]; 

我不确定这会让viewDidAppear被调用,但是你可以重写didMoveToParentViewController:在子控制器中,这将被调用,所以你可以把任何代码放在viewDidAppear中。

我遇到-viewWillAppear:不会再次调用问题。 谷歌search后,我来到这里。 我做了一些testing,发现-addSubview-addChildViewController:的调用顺序很重要。

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

情况1:

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

案例2:

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

默认情况下,外观callback会自动转发给子节点。 这是用shouldAutomaticallyForwardAppearanceMethods属性来确定的。 检查这个propery的值,如果它是NO,并且你的子viewController应该出现在容器的外观上,你应该在容器的控制器生命周期实现中用下面的方法通知孩子:

 - (void)viewWillAppear:(BOOL)animated { for (UIViewController *child in self.childViewControllers) { [child beginAppearanceTransition:YES animated:animated]; } } - (void)viewDidAppear:(BOOL)animated { [self.child endAppearanceTransition]; } - (void)viewWillDisappear:(BOOL)animated { for (UIViewController *child in self.childViewControllers) { [child beginAppearanceTransition:NO animated:animated]; } } - (void)viewDidDisappear:(BOOL)animated { [self.child endAppearanceTransition]; } 

自定义外观和旋转callback行为

解决了我的问题! 希望这会有所帮助。

根据Apple( https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html ),添加子视图控制器的API调用的正确顺序是:

 [self addChildViewController:childVC]; [self.view addSubview:childVC.view]; [childVC didMoveToParentViewController:self]; 

但是我仍然有一个问题,那就是在小孩VC中出现的问题不会偶尔被调用。 我的问题是有一个竞争条件,可能会导致上面的代码 viewDidAppear在容器视图控制器被调用之前执行。 确保已经调用了viewDidAppear(或者直到现在才推迟添加子VC)为我解决了这个问题。