繁体   English   中英

添加为子视图时未调用 UIViewController viewWillAppear

[英]UIViewController viewWillAppear not called when adding as subView

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

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

[self.scrollView addSubview:self.statisticsController.view];

我已经在统计视图控制器中放置了断点,并且正在调用viewDidLoad但没有调用viewWillAppear

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

您应该将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: not called 问题。 谷歌搜索后,我来到了这里。 我做了一些测试,发现-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)

默认情况下,外观回调会自动转发给孩子。 它由shouldAutomaticallyForwardAppearanceMethods属性确定。 检查此属性格式的值,如果是NO,如果你的孩子的viewController应在容器的外观右中出现,应该与以下容器的控制器生命周期实现方法通知孩子:

- (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];
}

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

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

正如另一个答案中提到的,当shouldAutomaticallyForwardAppearanceMethods设置为false时,父视图控制器可能不会调用viewWillAppear等。 UINavigationControllerUITabBarController可以做到这一点。 在这种情况下,您需要在子视图控制器上调用beginAppearanceTransition(_ isAppearing: Bool, animated: Bool)并在视图出现时将isAppearing设置为true ,反之亦然。

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

当您的自定义转换结束时,不要忘记在您的子视图控制器上调用endAppearanceTransition ,否则不会调用viewDidAppearviewDidDisappear

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

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

但是我仍然遇到问题,即子 VC 中的 viewWillAppear 没有偶尔被调用。 我的问题是存在竞争条件,可能导致上面的代码在容器视图控制器中的 viewDidAppear 被调用之前被执行。 确保 viewDidAppear 已经被调用(或推迟添加子 VC 直到它被调用)为我解决了这个问题。

以前的答案是正确的,但如果它对某人有帮助 - 如果您在子视图控制器中覆盖loadView ,则不会调用任何其他 UIViewController 方法。

我花了一些时间才意识到为什么我的代码运行不正常,直到我意识到我不小心覆盖了loadView而不是viewDidLoad

检查您的VC 是否为UINavigationViewController (或任何其他容器)。 在这种情况下, shouldAutomaticallyForwardAppearanceMethodsFalse并且不调用外观方法。

我无法理解你的问题和你的描述。 我的问题仅与此类似。

CustomTabBarController -> CustomUINavigationController -> RootViewcontroller

除非您切换到另一个选项卡并返回,否则不会调用 CustomUINavigationController 和 RootViewController 的 viewWillAppear。

解决方法是调用 super.viewWillAppear(animated: true)

override func viewWillAppear(_ animated: Bool) {
    **super.viewWillAppear(true)**
}

为了这个小错误,我挣扎了一天多。

如果您的视图控制器尚未加载其视图,则视图外观方法也不会被转发。 如果您在子视图控制器中覆盖loadView ,并且该视图已添加到视图层次结构中,则可能会发生这种情况。

在这种情况下,你可以做

addChild(childVC)
childVC.loadViewIfNeeded()
childVC.didMove(toParent: self)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM