我的应用程序针对无框设备(iPhoneX,Xs Xs max,Xr)有一些逻辑。目前它基于设备的型号工作,所以我通过DeviceKit框架检测型号。
但是我想将这种逻辑扩展到未来的无框设备上。可能在一年内我们会有一些额外的无框设备。那么,我该如何检测设备是否是无框的?它应该涵盖所有当前的无框设备和未来的设备。
我们无法依赖FaceID、safeAreaInset、屏幕高度或大小。那么,怎么办呢?
我的应用程序针对无框设备(iPhoneX,Xs Xs max,Xr)有一些逻辑。目前它基于设备的型号工作,所以我通过DeviceKit框架检测型号。
但是我想将这种逻辑扩展到未来的无框设备上。可能在一年内我们会有一些额外的无框设备。那么,我该如何检测设备是否是无框的?它应该涵盖所有当前的无框设备和未来的设备。
我们无法依赖FaceID、safeAreaInset、屏幕高度或大小。那么,怎么办呢?
func isIphoneX() -> Bool {
guard #available(iOS 11.0, *),
let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first else { return false }
return window.safeAreaInsets.top >= 44
}
如果您想检查UIViewController中的刘海屏,只需在方法viewSafeAreaInsetsDidChange()中设置isNotch标志即可。
open override func viewSafeAreaInsetsDidChange() {
super.viewSafeAreaInsetsDidChange()
isNotch = true
}
我只在模拟器上测试过它。它仅在所有方向的 X 设备中调用。
当你拥有
sceneDelegate.swift
类。这将起作用。
extension UIDevice {
var hasNotch: Bool {
if #available(iOS 11.0, *) {
if UIApplication.shared.windows.count == 0 { return false } // Should never occur, but…
let top = UIApplication.shared.windows[0].safeAreaInsets.top
return top > 20 // That seems to be the minimum top when no notch…
} else {
// Fallback on earlier versions
return false
}
}
}
safeTop = UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0
if safeTop > 20 {
print("Big family")
} else {
print("Before X")
}
Swift 5.0 最易于理解和适应您的条件。
var hasNotch: Bool {
if #available(iOS 11.0, *) {
if UIApplication.shared.windows.count == 0 { return false } // Should never occur, but…
let top = UIApplication.shared.windows[0].safeAreaInsets.top
return top > 20 // That seem to be the minimum top when no notch…
} else {
// Fallback on earlier versions
return false
}
}
UIApplication.shared.windows
已被弃用。如果方向未知,我还默认检查顶部插入。
extension UIDevice {
var hasNotch: Bool {
guard let firstScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
return false
}
guard let firstWindow = firstScene.windows.filter({$0.isKeyWindow}).first else {
return false
}
if UIDevice.current.orientation.isPortrait ||
UIDevice.current.orientation == .unknown {
return firstWindow.safeAreaInsets.top >= 44
} else {
return firstWindow.safeAreaInsets.left > 0 || firstWindow.safeAreaInsets.right > 0
}
}
}
这样你就可以覆盖所有的方向:
var hasTopNotch: Bool
{
if #available(iOS 11.0, *) {
var safeAreaInset: CGFloat?
if (UIApplication.shared.statusBarOrientation == .portrait) {
safeAreaInset = UIApplication.shared.delegate?.window??.safeAreaInsets.top
}
else if (UIApplication.shared.statusBarOrientation == .landscapeLeft) {
safeAreaInset = UIApplication.shared.delegate?.window??.safeAreaInsets.left
}
else if (UIApplication.shared.statusBarOrientation == .landscapeRight) {
safeAreaInset = UIApplication.shared.delegate?.window??.safeAreaInsets.right
}
return safeAreaInset ?? 0 > 24
}
return false
}
extension UIDevice {
var hasNotch: Bool {
let bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
return bottom > 0
}
}
使用 'UIDevice.current.hasNotch' 将返回 true 或 false
Swift 5
var hasNotch: Bool {
let bottom = UIApplication.shared.delegate?.window??.safeAreaInsets.bottom ?? 0
return bottom > 0
}