最合适的方法是什么来获得不安全区域的顶部和底部高度?


当前回答

试试这个:

在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
}

其他回答

这里有一个简单的答案,可以找到所有iphone的安全区域高度

let window = UIApplication.shared.windows[0]

let SafeAreaHeight = window.safeAreaLayoutGuide.layoutFrame.size.height

对于那些切换到横向模式的人,你必须确保在旋转后使用viewSafeAreaInsetsDidChange来获得最新的值:

private var safeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

override func viewSafeAreaInsetsDidChange() {
        if #available(iOS 11.0, *) {
            safeAreaInsets = UIApplication.shared.keyWindow!.safeAreaInsets
        }
}

这里有一个基于其他答案的免费函数,当你的rootController从任何地方布局时,它都应该是可调用的。你可以把它当做一个独立的函数。

    func safeAreaInsets() -> UIEdgeInsets? {
    (UIApplication
        .shared
        .keyWindow?
        .rootViewController)
        .flatMap {
            if #available(iOS 11.0, *) {
                return $0.view.safeAreaInsets
            } else {
                return .init(
                    top: $0.topLayoutGuide.length,
                    left: .zero,
                    bottom: $0.bottomLayoutGuide.length,
                    right: .zero
                )
            }
        }
}

要获得布局参考线之间的高度,只需这样做

let guide = view.safeAreaLayoutGuide
let height = guide.layoutFrame.size.height

所以全帧高度= 812.0,安全区高度= 734.0

下面的例子中,绿色视图的框架为guide.layoutFrame

或者使用SwiftUI GeometryReader api。

struct V: View {
    var body: some View {
        GeometryReader { geometry in
            Text("\(geometry.safeAreaInsets.top)")
            Text("\(geometry.safeAreaInsets.bottom)")
        }
    }
}


代码可能不起作用,但却说明了这个想法。