在我们的应用程序中,我们暂时隐藏状态栏作为动画的一部分,在两个需要不同状态栏样式的屏幕之间进行转换。
我们有一个百分比驱动的动画转换,启动后会隐藏动画状态栏,完成时会显示状态栏。
在iOS 11上,安全区域插入包括可变的状态栏高度,当隐藏时,安全区域的顶部插入点降至0高度。 这会重新调整我们的所有视图,并且在视图大小之间会出现可怕的跳跃。
我们仍然希望将我们的观点限制在安全区域,因为我们正在尝试支持iPhone X.
隐藏状态栏时,我们可以暂时禁用对安全区域insets的更改吗?
答案 0 :(得分:7)
设置为safe area
的约束受状态栏以及屏幕上的视图实际位置及其变换的影响。如果您始终只想将顶部(或底部)安全区域高度应用于视图约束,则可以使用自定义约束来执行此操作。
以下约束会自动将其constant
值设置为设备顶部安全区域高度的高度,不受状态栏或其他参数的影响。要使用它,请将任何约束的类更改为此类,并且它们的constant
将始终是安全区域高度。请注意,旋转设备时不会更改其值。
<强> ObjC 强>
@interface TopSafeAreaContraint : NSLayoutConstraint
@end
@implementation TopSafeAreaContraint
- (void)awakeFromNib {
[super awakeFromNib];
if (@available(iOS 11.0, *)) {
UIEdgeInsets insets = [UIApplication sharedApplication].keyWindow.safeAreaInsets;
self.constant = MAX(insets.top, 20.0);
} else {
// Pre-iOS 11.0
self.constant = 20.0;
}
}
@end
<强> SWIFT 强>
class TopSafeAreaConstraint: NSLayoutConstraint {
override func awakeFromNib() {
super.awakeFromNib()
if #available(iOS 11.0, *) {
let insets = UIApplication.shared.keyWindow?.safeAreaInsets ?? .zero
self.constant = max(insets.top, 20)
} else {
// Pre-iOS 11.0
self.constant = 20.0
}
}
}
答案 1 :(得分:2)
我一直遇到类似的问题,所以我想出了一个略有不同的方法。这不是问题的直接答案。对于我来说,这是一种解决方法。
我有两个不同的视图控制器,两个都必须具有导航栏(但不需要导航控制器)。第一视图控制器以模态方式呈现第二视图。问题在于第二个视图控制器仅是横向视图,这意味着在具有边到边显示的iPhone上,prefersStatusBarHidden
的任何替代都将被忽略,并且系统始终返回true
(请参见{{3} }。
我所做的是通过自定义视图模拟状态栏的高度,然后在viewDidLoad(_:)
中调整高度约束常数。
我没有丑陋的导航栏,或者视图控制器在那之后跳转。
答案 2 :(得分:1)
获取对安全区域顶部约束的引用,并尝试更改该约束的常量以调整状态栏的隐藏/显示。这适用于我,虽然在一个稍微不同的情况下,我在prefersStatusBarHidden方法中设置约束常数以响应显示/隐藏工具栏。
答案 3 :(得分:0)
您通常希望滚动视图位于状态栏(安全区域)下,只需调整其内容插入,而不是仅在安全区域内进行布局。默认情况下,UIScrollView
会自动调整调整。请参阅contentInsetAdjustmentBehavior
。
如果您有滚动视图完整视图大小(在安全区域下),隐藏和显示状态栏对我来说非常有效,即使在滚动视图中自动修改了安全区域插入。
答案 4 :(得分:0)