视图控制器容器偶尔会错过子控制器中的 viewWillAppear

Posted

技术标签:

【中文标题】视图控制器容器偶尔会错过子控制器中的 viewWillAppear【英文标题】:View controller container sporadically misses viewWillAppear in child controllers 【发布时间】:2014-04-23 16:11:00 【问题描述】:

我有一个带有子视图的根视图控制器作为子视图控制器视图的包装器。基本思想是我的根控制器有一个左右视图控制器,它们都出现在屏幕上(类似于 splitviewcontroller)。加载时会在根视图控制器上弹出一个模式视图并询问详细信息。模态视图然后联系服务器,并在得到响应后关闭。然后根控制器使用以下代码添加子视图控制器:

[self addViewController:self.leftViewController];
[self addViewController:self.rightViewController];

[self addView:self.rightViewController.view ToWrapper:self.rightViewWrapper];
[self addView:self.leftViewController.view ToWrapper:self.leftViewWrapper];

添加视图控制器在哪里:

[self addChildViewController:controller];
[controller didMoveToParentViewController:self];

而addViewToWrapper只是将视图控制器的视图添加到rootViewController的相关子视图中,如下:

[[viewWrapper.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
newSubview.frame = viewWrapper.contentView.bounds;
newSubview.autoresizingMask = UIViewAutoresizingFlexibleHeight |    UIViewAutoresizingFlexibleWidth;
[viewWrapper.contentView addSubview:newSubview];

99% 的时间都可以正常工作。两个视图都会立即出现,并且 viewWillAppear 会在两个子控制器中触发。但是,有时屏幕会在短时间内保持白色,并且 viewWillAppear 不会在右侧视图控制器(编辑:和左侧)中触发。所有其他视图生命周期方法都会触发,只是不会触发 viewWillAppear。

不幸的是,我不能为整个类提供代码,因为它很复杂而且是专有的。但是,对于这种间歇性行为的描述是否有任何线索?

【问题讨论】:

我还应该补充一点,这是在 appDelegate 启动应用程序之后发生的。模态视图后面是 2 个空白占位符。当模式视图被关闭时,这些控制器被移除,并添加新的子控制器。 一个非常重要的线索是删除模态屏幕,消除了问题。在模态屏幕关闭期间的某些东西会阻止子视图控制器的视图出现。 【参考方案1】:

对此的一些想法:

一个

您的收容方法似乎没有被正确调用。对于每个 viewController,它们应该如下所示:

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

视图应在addChilddidMove 调用之间添加到父视图。

两个

据我所知,一次只能进行一次演示或解雇。 IE。如果您尝试在关闭模式的同时呈现(添加)您的子视图控制器,您将在控制台日志中看到错误,并且您的“添加”操作将不会发生。

我的建议是在模态视图控制器上创建一个委托协议。在dismissViewControllerAnimated:completion:的完成块中,调用你的委托方法:

[self dismissViewControllerAnimated:YES completion:^
   if ([weakSelf.delegate respondsToSelector:@selector(settingsViewControllerDidDismiss:)])
   
       [weakSelf.delegate settingsViewControllerDidDismiss:self];
   
];

在您的 rootViewController 中,您将开始在 settingsViewControllerDidDismiss 或您决定调用该方法的任何内容中添加其子项。关键是“添加”操作在解除操作之后开始。

希望这会有所帮助。

【讨论】:

啊,我没有意识到添加视图的顺序很重要。这似乎是导致问题的模态视图。烦人的是,添加操作是由与解除操作完全无关的事件触发的,所以我必须以某种方式从两者中触发它。 听起来不错,如果您最终认为这是正确答案,请不要忘记将其标记为正确答案。我相当确定您遇到的问题是由于同时展示/解雇造成的。 这几乎肯定是答案。我添加了一个通知,告诉模态框在其后面的视图控制器完全加载后关闭(可能不是正确的方法,但从 UI 角度来看是最干净的)。从那以后我就再也没有看到过这个问题。 这是个好消息!听起来该流程最适合您的 UI 案例,而不是通过上面的委托内容概述的相反方式。无论哪种方式,都很好!

以上是关于视图控制器容器偶尔会错过子控制器中的 viewWillAppear的主要内容,如果未能解决你的问题,请参考以下文章

将子视图控制器链接到情节提要中的父视图控制器

拆分视图控制器偶尔会在 iOS 13 上的 iPhone 上显示详细视图

子视图控制器中的导航堆栈

呈现子视图控制器的自定义容器视图控制器子项

如何在 swift 中从父视图访问容器视图子视图

子视图控制器的视图未显示在容器中