iOS:检测设备是否为iPhone X系列(无边框)

42

我的应用程序针对无框设备(iPhoneX,Xs Xs max,Xr)有一些逻辑。目前它基于设备的型号工作,所以我通过DeviceKit框架检测型号。

但是我想将这种逻辑扩展到未来的无框设备上。可能在一年内我们会有一些额外的无框设备。那么,我该如何检测设备是否是无框的?它应该涵盖所有当前的无框设备和未来的设备。

我们无法依赖FaceID、safeAreaInset、屏幕高度或大小。那么,怎么办呢?


6
不要根据屏幕大小在你的应用程序中做决定。这种方法不可扩展且难以维护。 - Cristik
1
@Cristik,是的,我知道。 - Mark cubn
1
@ slickdaddy,这个应用程序是为客户而设计的,他们不想推送太多更新,我希望能节省他们的时间。 - Mark cubn
请参考以下内容的翻译:https://dev59.com/h1YO5IYBdhLWcg3wMO1y#46192822 - Anbu.Karthik
@Cristik 你的意思是什么?每个移动端断点样式都是基于屏幕尺寸在你的应用程序中做出的“决策”。 - duhaime
显示剩余2条评论
18个回答

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

0

如果您想检查UIViewController中的刘海屏,只需在方法viewSafeAreaInsetsDidChange()中设置isNotch标志即可。

open override func viewSafeAreaInsetsDidChange() {
    super.viewSafeAreaInsetsDidChange()
    isNotch = true
}

我只在模拟器上测试过它。它仅在所有方向的 X 设备中调用。


0

当你拥有

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

0
safeTop = UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0

if safeTop > 20 { 
   print("Big family")
} else {
   print("Before X")
}

Swift 5.0 最易于理解和适应您的条件。


这对我不起作用 - 在使用 iPhone 14 时打印了“X之前”。 - Joseph

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

参考文献:https://developer.apple.com/forums/thread/127113?page=2 - idris yıldız

0
我在Saafo的回答基础上进行了改进,因为在iOS 15.0中,UIApplication.shared.windows已被弃用。如果方向未知,我还默认检查顶部插入。

xcode warning on deprecated function

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


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
}

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

在编程中,推崇认真描述你的代码,考虑在你的回答中添加一些说明,这是一个好的实践。 - zhisme
1
还要描述您的答案与现有8个答案的区别。 - fishinear

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接