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


当前回答

Swift 5, Xcode 11.4

`UIApplication.shared.keyWindow` 

它将给出弃用警告。" keyWindow "在iOS 13.0中已弃用:不应该用于支持多场景的应用程序,因为它会在所有连接的场景中返回一个键窗口。我用这种方法。

extension UIView {

    var safeAreaBottom: CGFloat {
         if #available(iOS 11, *) {
            if let window = UIApplication.shared.keyWindowInConnectedScenes {
                return window.safeAreaInsets.bottom
            }
         }
         return 0
    }

    var safeAreaTop: CGFloat {
         if #available(iOS 11, *) {
            if let window = UIApplication.shared.keyWindowInConnectedScenes {
                return window.safeAreaInsets.top
            }
         }
         return 0
    }
}

extension UIApplication {
    var keyWindowInConnectedScenes: UIWindow? {
        return windows.first(where: { $0.isKeyWindow })
    }
}

其他回答

对于iPhone 14设备使用如下。

let app = UIApplication.shared
var statusBarHeight: CGFloat = 0.0
let window = app.windows.filter {$0.isKeyWindow}.first
statusBarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
let topPadding = window?.safeAreaInsets.top ?? 0.0
statusBarHeight = statusBarHeight >= topPadding ? statusBarHeight:topPadding

对于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
    }

试试这个:

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

或者使用SwiftUI GeometryReader api。

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


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

斯威夫特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
            
        }
        
    }
}

在构建应用程序时,您将看到安全区域填充。