从 viewDidAppear 呈现时,模态弹出框控制器不显示其内容
Posted
技术标签:
【中文标题】从 viewDidAppear 呈现时,模态弹出框控制器不显示其内容【英文标题】:Modal popover controller does not show its content when presented from viewDidAppear 【发布时间】:2017-03-21 13:17:57 【问题描述】:我有一个视图控制器,它在另一个视图控制器上显示为模态。如果以viewDidAppear
中的animated:NO
呈现,则在第二次呈现时不会显示其内容。我已将问题缩小到这一点:我添加了两个通过 segue 连接到情节提要的控制器,每个控制器在 viewDidAppear
中呈现相同的弹出框控制器。
它们中的每一个都是同一类的一个实例:
#import "ViewController.h"
#import "PopupViewController.h"
@interface ViewController () <UIPopoverPresentationControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
- (void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
[self showPopover];
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
return UIModalPresentationNone;
- (void)showPopover
PopupViewController* popoverController = [[PopupViewController alloc] initWithNibName:NSStringFromClass([PopupViewController class]) bundle:nil];
popoverController.modalPresentationStyle = UIModalPresentationPopover;
popoverController.preferredContentSize = CGRectInset(self.view.bounds, 20, 100).size;
popoverController.popoverPresentationController.sourceView = self.view;
popoverController.popoverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds), 0, 0);
popoverController.popoverPresentationController.permittedArrowDirections = 0;
popoverController.popoverPresentationController.delegate = self;
[self presentViewController:popoverController animated:NO completion:nil];
@end
弹出框在应用启动时正确显示,但在按下第二个视图控制器和点击返回按钮时为空。如果我将animated
更改为YES
,弹出框会正确显示。
编辑:如果我在 Xcode 中调试视图层次结构,视图会正确显示,所有帧都应该是:
这是它在设备上的样子(左边是正确的弹出框,右边是空的):
【问题讨论】:
当你推送第二个视图控制器时,弹出框是否会被移除,可能在viewDidDisappear
中?
在进入第二个视图控制器之前,我通过点击它周围的阴影来关闭弹出框
你在等待第一个弹出框消失吗?您的控制台中有任何警告吗?
@Sulthan,没有警告,第一个弹出框完全消失。
我已经重现了您的问题,但我仍在努力寻找导致这种行为的原因。可以通过在显示弹出框之前添加一个小延迟(使用dispatch_after
)来解决该问题,因此它可能与视图控制器层次结构中的某些问题有关。我在使用弹出框方面的经验非常糟糕。他们在许多情况下表现得很奇怪。
【参考方案1】:
这个问题很容易重现。我开始记录事件,这似乎是由UINavigationController
处理动画的方式引起的。
当viewDidAppear
被推送的控制器调用时,动画还没有结束。您可以通过检查UINavigationControllerDelegate
中的navigationController:didShowViewController
方法来亲自查看。
事件日志如下所示:
Navigation controller will show VC 1
VC 1 did layout subviews
VC 1 did layout subviews
VC 0 did move to parent <UINavigationController: 0x7feaf181ec00>
VC 1 did appear
VC 1 did move to parent <UINavigationController: 0x7feaf181ec00>
Navigation controller did show VC 1
请注意,第二个控制器甚至没有完全移动到 viewDidAppear:
中的父级。
我发现的唯一可行的解决方法是:
- (void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
dispatch_async(dispatch_get_main_queue(), ^
[self showPopover];
);
这将使导航控制器完成其内部工作。
请注意,在没有动画的情况下推送时不会出现问题,因此这可能是由于我们试图从另一个动画完成块显示没有动画的视图控制器,这意味着视图控制器层次结构事件的顺序被破坏。添加dispatch_async
将代码从完成块中移出,一切都开始正常工作。
【讨论】:
非常感谢,看来这解决了问题。以上是关于从 viewDidAppear 呈现时,模态弹出框控制器不显示其内容的主要内容,如果未能解决你的问题,请参考以下文章
从模态呈现的视图控制器内部呈现 UIPopoverController