从viewDidAppear

时间:2017-03-21 13:17:57

标签: ios objective-c uikit uipopovercontroller

我有一个视图控制器,它显示为另一个视图控制器的模态。如果从animated:NO显示viewDidAppear,则第二次显示时不会显示其内容。我已经解决了这个问题:我已经添加了两个通过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中调试视图层次结构,视图会正确显示,所有帧都应该是:

View hierarchy

这就是它在设备上的样子(左侧是正确的弹出框,右侧是空的): Example

1 个答案:

答案 0 :(得分:1)

此问题可以轻松复制。我开始记录事件,这似乎是由UINavigationController处理动画的方式引起的。

为推送的控制器调用viewDidAppear时,动画尚未完成。您可以通过查看navigationController:didShowViewController中的UINavigationControllerDelegate方法自行查看。

事件日志如下所示:

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会从完成块移动代码,一切都开始正常工作。