viewWillTransitionToSize safeArea和presentViewController

时间:2018-09-18 15:34:17

标签: ios objective-c rotation

在旋转屏幕时,我需要对内部视图进行一些重新计算。 我在那里嵌入了UIViewController和UIScrollView。内部视图取决于ScrollView框架的大小。

所以在UIViewController中,我有以下代码:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
DDLogDebug(@">>>>>>>>>>>>> %@", NSStringFromCGSize(size));
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    DDLogDebug(@"+++++++++ mainScroll %@", NSStringFromCGRect(_mainScroll.frame));
    CGRect newFrame = CGRectMake(0, 0, size.width, size.height);
    self.view.frame = newFrame;
    [self.view.layer layoutIfNeeded];
    DDLogDebug(@"--------- mainScroll %@", NSStringFromCGRect(_mainScroll.frame));

    // and update the children

}
completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
}];
}

到目前为止,一切都很好。我看到在手动设置控制器视图的框架大小并调用layoutIfNeeded(或layoutSubviews-相同的结果)之后,可以适当地调整mainScroll的大小,包括考虑safeArea约束,一切都很好。

现在,在代码中的某个地方有一个弹出控制器,称为

[self presentViewController:controllerToPresent animated:NO completion:nil];

没什么有趣的,但是上面介绍的这个控制器位于另一个控制器之上,并且mainScroll也位于后台。 现在,尝试旋转屏幕会导致如下情况:layoutIfNeeded之后mainScroll的大小比没有弹出控制器时高20点。似乎safeArea指南/约束没有在后台应用。关闭弹出窗口控制器后,mainScroll超出了预期,并且视图错位了…… 有什么提示吗?

为什么“ presentViewController”会影响调用者在viewWillTransitionToSize方面的行为?

1 个答案:

答案 0 :(得分:0)

为了解决我遇到的以下解决方案的挑战:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        [self updateLayoutAfterRotation:size];
    }
    completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
    }];
}

- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    [self updateLayoutAfterRotation:self.view.frame.size];
}

- (void)updateLayoutAfterRotation:(CGSize)size {
    CGRect newFrame = CGRectMake(0, 0, size.width, size.height);
    self.view.frame = newFrame;
    [self.view.layer layoutIfNeeded];

    // Here is custom code to adopt layout
}

有趣的是,当此viewController自身旋转(屏幕上的顶视图)时,首先收到viewSafeAreaInsetsDidChange,然后收到viewWillTransitionToSize。 但是,如果控制器的视图隐藏在弹出式控制器的后面,则调用的顺序相反。 viewSafeAreaInsetsDidChange在关闭弹出控制器时(即在屏幕旋转时不再显示)被首先调用