【问题标题】:viewWillTransitionToSize safeArea and presentViewControllerviewWillTransitionToSize safeArea 和 presentViewController
【发布时间】:2019-02-22 16:44:52
【问题描述】:

在屏幕旋转时,我需要重新计算内部视图。 我在那里嵌入了一个 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 方面的行为?

【问题讨论】:

    标签: ios objective-c rotation


    【解决方案1】:

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

    - (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 在弹出控制器关闭时首先被调用(即屏幕旋转时不再调用)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-03
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多