UIKit中如何检测用户设备有动态岛?

Tar*_*ney 9 uikit swift dynamic-island

在我的应用程序中,我实现了拉动刷新功能和自定义加载图标。在具有动态岛的iPhone中,它与我的加载图标重叠。

我想检测是否有动态岛的设备。如果有的话,我会在上面添加一些顶部空间。

wli*_*xcc 11

  1. 根据Live Activity文档,我们只能检测设备是否支持Live Activity,但不知道设备是否有动态孤岛

  2. 我使用窗口safeAreaInsets值来检测动态孤岛。当设备方向为纵向时, safeAreaInsets.top等于59(显示缩放默认值)或51(显示缩放大文本)。

  3. 这很可能支持 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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我用多种不同的设备对此进行了测试,以确保与其他尺寸没有冲突,并且它们都有效,这是目前更面向未来的解决方案。 (2认同)

Tha*_*Phi 5

目前,据我所知,动态岛将于ActivityKit2022 年末包含在内。您可以从此链接查看 ActivityKitApple 的相关主题。苹果没有提供检查动态岛是否在设备上的方法。

但有一个解决方法可以让您获得您想要的东西。目前动态岛iPhone 14 Pro仅在和上可用iPhone 14 Pro Max。所以只需要检查这两个设备。

更新:感谢此链接的 type model、 name model type ofiPhone 14 ProiPhone 14 Pro Maxis 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
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

let value = UIDevice().checkIfHasDynamicIsland()
print("value: ", value)
Run Code Online (Sandbox Code Playgroud)

  • 亲爱的@Ahmadreza,iphone 15什么时候发布或者有其他方法可以实现我会更新答案 (2认同)