最合适的方法是什么来获得不安全区域的顶部和底部高度?
当前回答
试试这个:
在Objective C中
if (@available(iOS 11.0, *)) {
UIWindow *window = UIApplication.sharedApplication.windows.firstObject;
CGFloat topPadding = window.safeAreaInsets.top;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
}
在斯威夫特
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
let topPadding = window?.safeAreaInsets.top
let bottomPadding = window?.safeAreaInsets.bottom
}
在Swift - iOS 13.0及以上
//使用windows数组中的第一个元素,KeyWindow已弃用
if #available(iOS 13.0, *) {
let window = UIApplication.shared.windows.first
let topPadding = window.safeAreaInsets.top
let bottomPadding = window.safeAreaInsets.bottom
}
其他回答
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
CGFloat fBottomPadding = window.safeAreaInsets.bottom;
Swift 4,5
使用约束将视图固定到安全区域锚点可以在视图控制器生命周期的任何地方完成,因为它们由API排队,并在视图加载到内存后进行处理。然而,获取安全区值需要等待视图控制器生命周期的结束,如viewDidLayoutSubviews()。
这将插入到任何视图控制器:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let topSafeArea: CGFloat
let bottomSafeArea: CGFloat
if #available(iOS 11.0, *) {
topSafeArea = view.safeAreaInsets.top
bottomSafeArea = view.safeAreaInsets.bottom
} else {
topSafeArea = topLayoutGuide.length
bottomSafeArea = bottomLayoutGuide.length
}
// safe area values are now available to use
}
我更喜欢这种方法,而不是将它从窗口中删除(如果可能的话),因为这是API的设计方式,更重要的是,在所有视图更改期间,值都会更新,比如设备方向更改。
然而,一些自定义呈现的视图控制器不能使用上述方法(我怀疑是因为它们在瞬态容器视图中)。在这种情况下,你可以从根视图控制器获取值,它总是在当前视图控制器生命周期的任何地方可用。
anyLifecycleMethod()
guard let root = UIApplication.shared.keyWindow?.rootViewController else {
return
}
let topSafeArea: CGFloat
let bottomSafeArea: CGFloat
if #available(iOS 11.0, *) {
topSafeArea = root.view.safeAreaInsets.top
bottomSafeArea = root.view.safeAreaInsets.bottom
} else {
topSafeArea = root.topLayoutGuide.length
bottomSafeArea = root.bottomLayoutGuide.length
}
// safe area values are now available to use
}
斯威夫特4
if let window = UIApplication.shared.windows.first {
let topPadding = window.safeAreaInsets.top
let bottomPadding = window.safeAreaInsets.bottom
}
从课堂使用
class fitToTopInsetConstraint: NSLayoutConstraint {
override func awakeFromNib() {
if let window = UIApplication.shared.windows.first {
let topPadding = window.safeAreaInsets.top
self.constant += topPadding
}
}
}
class fitToBottomInsetConstraint: NSLayoutConstraint {
override func awakeFromNib() {
if let window = UIApplication.shared.windows.first {
let bottomPadding = window.safeAreaInsets.bottom
self.constant += bottomPadding
}
}
}
在构建应用程序时,您将看到安全区域填充。
试试这个:
在Objective C中
if (@available(iOS 11.0, *)) {
UIWindow *window = UIApplication.sharedApplication.windows.firstObject;
CGFloat topPadding = window.safeAreaInsets.top;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
}
在斯威夫特
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
let topPadding = window?.safeAreaInsets.top
let bottomPadding = window?.safeAreaInsets.bottom
}
在Swift - iOS 13.0及以上
//使用windows数组中的第一个元素,KeyWindow已弃用
if #available(iOS 13.0, *) {
let window = UIApplication.shared.windows.first
let topPadding = window.safeAreaInsets.top
let bottomPadding = window.safeAreaInsets.bottom
}
对于iOS 13+/Swift 5,除了这个,没有其他方法适合我:
if #available(iOS 13.0, *) {
topPadding = UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0
bottomPadding = UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0
}
推荐文章
- 禁用所呈现视图控制器的交互式撤销
- 在Swift中转换字符串为日期
- 点击按钮时如何打开手机设置?
- 如何使用UIVisualEffectView来模糊图像?
- 如何修复UITableView分隔符在iOS 7?
- 故事板中的自定义单元格行高设置没有响应
- 如何改变时间和时区在iPhone模拟器?
- 在Swift中使用自定义消息抛出错误/异常的最简单方法?
- 编译器错误:带有Objective-C选择器的方法与前面带有相同Objective-C选择器的声明冲突
- 如何在Swift中获得唯一的设备ID ?
- 如何在Swift中获得枚举值的名称?
- 我如何知道何时UITableView完成了ReloadData?
- 复制文本到剪贴板与iOS
- 在Swift中根据字符串计算UILabel的大小
- 如何调用手势点击在UIView编程在迅速