swift 如何在UIKit中检测用户设备是否存在动态岛?

rvpgvaaj  于 2023-04-19  发布在  Swift
关注(0)|答案(3)|浏览(256)

在我的应用程序中,我实现了拉刷新功能和自定义加载图标。在有动态岛的iPhone中,它与我的加载图标重叠。
我想检测设备是否有动态岛。如果有,我将添加一些顶部空间。

cclgggtu

cclgggtu1#

1.根据live activity文档,我们只能检测设备是否支持Live activity,不知道设备是否有动态岛
1.我使用window safeAreaInsets值检测动态岛,当设备方向为纵向时,safeAreaInsets.top等于59(显示缩放默认值),或51(显示缩放大文本)。
1.这很可能支持iPhone15 Pro/iPhone15 Pro Max和更高型号。
用法:print(UIDevice.current.hasDynamicIsland)

extension UIDevice {
    
    // Get this value after sceneDidBecomeActive
    var hasDynamicIsland: Bool {
        // 1. dynamicIsland only support iPhone
        guard userInterfaceIdiom == .phone else {
            return false
        }
               
        // 2. Get key window, working after sceneDidBecomeActive
        guard let window = (UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.flatMap { $0.windows }.first { $0.isKeyWindow}) else {
            print("Do not found key window")
            return false
        }
       
        // 3.It works properly when the device orientation is portrait
        return window.safeAreaInsets.top >= 51
    }
}
zxlwwiss

zxlwwiss2#

目前,据我所知,动态岛将在2022年底包含在ActivityKit中。您可以从this link for ActivityKitApple's thread about it中查看。并且Apple没有提供检查动态岛是否在设备上的方法。
但是有一个解决方案可以让你得到你想要的东西。目前动态岛只在iPhone 14 ProiPhone 14 Pro Max上可用。所以只需要检查这两个设备。

更新:感谢这个类型模型的链接,iPhone 14 ProiPhone 14 Pro Max的名称模型类型是iPhone15,2iPhone15,3,所以我们只需要检查这些情况。

代码将是这样的

extension UIDevice {
    func checkIfHasDynamicIsland() -> Bool {
        if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
            let nameSimulator = simulatorModelIdentifier
            return nameSimulator == "iPhone15,2" || nameSimulator == "iPhone15,3" ? true : false
        }
        
        var sysinfo = utsname()
        uname(&sysinfo) // ignore return value
        let name =  String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
        return name == "iPhone15,2" || name == "iPhone15,3" ? true : false
    }
}

用途

let value = UIDevice().checkIfHasDynamicIsland()
print("value: ", value)
7hiiyaii

7hiiyaii3#

我使用Device framework并在扩展中实现了一个额外的computed属性来检测动态岛的可用性。

extension Device {
    static var hasDynamicIsland: Bool {
        switch version() {
        case .iPhone14Pro, .iPhone14Pro_Max:
            return true
        case .iPhone2G:
            return false
        case .iPhone3G:
            return false
        case .iPhone3GS:
            return false
        case .iPhone4:
            return false
        case .iPhone4S:
            return false
        case .iPhone5:
            return false
        case .iPhone5C:
            return false
        case .iPhone5S:
            return false
        case .iPhone6:
            return false
        case .iPhone6Plus:
            return false
        case .iPhone6S:
            return false
        case .iPhone6SPlus:
            return false
        case .iPhoneSE:
            return false
        case .iPhone7:
            return false
        case .iPhone7Plus:
            return false
        case .iPhone8:
            return false
        case .iPhone8Plus:
            return false
        case .iPhoneX:
            return false
        case .iPhoneXS:
            return false
        case .iPhoneXS_Max:
            return false
        case .iPhoneXR:
            return false
        case .iPhone11:
            return false
        case .iPhone11Pro:
            return false
        case .iPhone11Pro_Max:
            return false
        case .iPhoneSE2:
            return false
        case .iPhone12Mini:
            return false
        case .iPhone12:
            return false
        case .iPhone12Pro:
            return false
        case .iPhone12Pro_Max:
            return false
        case .iPhone13Mini:
            return false
        case .iPhone13:
            return false
        case .iPhone13Pro:
            return false
        case .iPhone13Pro_Max:
            return false
        case .iPhone14:
            return false
        case .iPhone14Plus:
            return false
        case .iPad1:
            return false
        case .iPad2:
            return false
        case .iPad3:
            return false
        case .iPad4:
            return false
        case .iPad5:
            return false
        case .iPad6:
            return false
        case .iPad7:
            return false
        case .iPad8:
            return false
        case .iPad9:
            return false
        case .iPadAir:
            return false
        case .iPadAir2:
            return false
        case .iPadAir3:
            return false
        case .iPadAir4:
            return false
        case .iPadMini:
            return false
        case .iPadMini2:
            return false
        case .iPadMini3:
            return false
        case .iPadMini4:
            return false
        case .iPadMini5:
            return false
        case .iPadMini6:
            return false
        case .iPadPro9_7Inch:
            return false
        case .iPadPro12_9Inch:
            return false
        case .iPadPro10_5Inch:
            return false
        case .iPadPro12_9Inch2:
            return false
        case .iPadPro11_0Inch:
            return false
        case .iPadPro12_9Inch3:
            return false
        case .iPadPro11_0Inch2:
            return false
        case .iPadPro11_0Inch3:
            return false
        case .iPadPro12_9Inch4:
            return false
        case .iPadPro12_9Inch5:
            return false
        case .iPodTouch1Gen:
            return false
        case .iPodTouch2Gen:
            return false
        case .iPodTouch3Gen:
            return false
        case .iPodTouch4Gen:
            return false
        case .iPodTouch5Gen:
            return false
        case .iPodTouch6Gen:
            return false
        case .iPodTouch7Gen:
            return false
        case .simulator:
            return false
        case .unknown:
            return false
        }
    }
}

相关问题