iPhone X竖屏时占满整个屏幕的控制器的view的safeAreaInsets是(44,0,34,0),横屏是(0,44,21,44),inset后的区域正好是safeAreaLayoutGuide区域
既然如此,对于自定义的顶部导航栏来说,我们可以给导航栏的高度加上一个vc.view.safeAreaInsets.top,让他变高一点就可以了,这样在X上,竖屏时top = 44, 横屏时top = 0,导航栏的高度能响应改变需要注意的是,无论safeAreaLayoutGuide还是safeAreaInsets都是iOS11才能使用的。
对于safeAreaInsets,我们可以把版本判断写在一个函数里,safeAreaInsets在viewWillApperar之后才会有值,
(可以看到,viewSafeAreaInsetsDidChange调用时机很早,在viewWillAppear后,这是为什么出现多余动画的原因。并且“pushVC”的safeAreaInsets直到viewSafeAreaInsetsDidChange调用前,都是UIEdgeInsetsZero,之后才是正确的UIEdgeInsets(top: 44.0, left: 0.0, bottom: 34.0, right: 0.0)
并且viewSafeAreaInsetsDidChange后面会调用两次viewDidLayoutSubviews,所以我们应该把改变高度或布局的代码都写在viewDidLayoutSubviews里,这样就不会有多余的动画效果了。需要注意viewDidLayoutSubviews可能会由别的操作频繁触发,所以如果调整safeArea布局的代码比较耗时,可以考虑加上一个状态标记,只在didChange后执行一次布局调
),所以布局代码如果在viewDidLaod里面是没有safeAreaInsets的,但由于viewDidLayoutSubviews的触发过程很多,因此加标记,不行的话只有定值适配
if(@available(iOS11.0, *)) {
[testViewmas_makeConstraints:^(MASConstraintMaker*make) {
make.top.equalTo(@(self.view.safeAreaInsets.top == 0? [[UIApplication sharedApplication] statusBarFrame].size.height: self.view.safeAreaInsets.top));
make.bottom.equalTo(@(([UIScreenmainScreen].bounds.size.height>812.0) ? -34:0));
make.left.width.equalTo(self.view);
}];
}else{
[testViewmas_makeConstraints:^(MASConstraintMaker*make) {
make.top.equalTo(@([[UIApplication sharedApplication] statusBarFrame].size.height));
make.bottom.equalTo(@(0));
make.left.width.equalTo(self.view);
}];
}