【问题标题】:iOS: Detect if the device is iPhone X family (frameless)iOS:检测设备是否为 iPhone X 系列(无框)
【发布时间】:2019-02-23 10:17:21
【问题描述】:

在我的应用中,有一些适用于无框设备(iPhoneX、Xs Xs max、Xr)的逻辑。目前它基于设备的模型工作,因此,我通过 DeviceKit 框架检测模型。

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

我们不能依赖 faceID、safeAreaInset、屏幕高度或尺寸。那么,然后呢?

【问题讨论】:

  • 不要根据屏幕大小在您的应用中做出决定。它根本无法扩展且难以维护。
  • @Cristik,是的,我知道
  • Apple 没有制造很多运行 iOS 的不同型号,因此只需在设备推出时更新设备列表。我想这将是每年大约 10 分钟的工作。
  • @slickdaddy,该应用程序是为客户准备的,他们不想推送很多更新,我想节省他们的时间

标签: ios iphone swift uiview ios11


【解决方案1】:

你可以为一流的“fitler”,比如:

var hasTopNotch: Bool {
    if #available(iOS 11.0, tvOS 11.0, *) {
        return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 20
    }
    return false
}

【讨论】:

  • 这不适用于 statusBarHeight 为 24pt 的 iPad Pro
  • MarekR -> 尝试“.bottom 而不是 .top”
【解决方案2】:

这样你就可以覆盖所有方向:

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
}

【讨论】:

    【解决方案3】:

    这对任何方向都有效。 无需担心 11.0 之前的 iOS 版本,因为 iPhone X 最低版本是 11.0。 Source

    extension UIDevice {
    
        var hasNotch: Bool {
            if #available(iOS 11.0, *) {
               return UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0 > 0
            }
            return false
       }
    }
    

    【讨论】:

    • keyWindow 现已弃用。
    【解决方案4】:

    我这样做是因为 iPadPro 的 safeAreaInsets 非零。

    extension UIDevice {
    
        /// Returns 'true' if the device has a notch
        var hasNotch: Bool {
            guard #available(iOS 11.0, *), let window = UIApplication.shared.keyWindow else { return false }
            let orientation = UIApplication.shared.statusBarOrientation
            if orientation.isPortrait {
                return window.safeAreaInsets.top >= 44
            } else {
                return window.safeAreaInsets.left > 0 || window.safeAreaInsets.right > 0
            }
        }
    
    }
    

    【讨论】:

      【解决方案5】:
      extension UIDevice {
          var hasNotch: Bool
          {
              if #available(iOS 11.0, *)
              {
                  let bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
                  return bottom > 0
              } else
              {
                  // Fallback on earlier versions
                  return false
              }
          }
      }
      

      使用者

      if UIDevice.current.hasNotch 
      {
          //... consider notch
      } 
      else 
      {
         //... don't have to consider notch
      }
      

      【讨论】:

        【解决方案6】:

        斯威夫特 5

        var hasNotch: Bool {
            if #available(iOS 11.0, tvOS 11.0, *) {
                let bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
                return bottom > 0
            } else {
                return false
            }
        }
        

        【讨论】:

          【解决方案7】:

          由于keyWindow was deprecated in iOS 13,基于从here找到keyWindow的解决方案,这个对我有用

          extension UIDevice {
              var hasNotch: Bool {
                  if #available(iOS 11.0, *) {
                      let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
                      return keyWindow?.safeAreaInsets.bottom ?? 0 > 0
                  }
                  return false
              }
          
          }
          

          【讨论】:

            【解决方案8】:

            支持 Swift 5、iOS 14

            感谢@Tanin 和@DominicMDev,因为keyWindow was deprecated in iOS 13the iPad Pro has non-zero safeAreaInsets,这对我来说很好。

            (已在 iPhone 8iPhone 11 ProiPad Pro (11-inch)(2nd gen) 模拟器上测试)

            extension UIDevice {
                /// Returns `true` if the device has a notch
                var hasNotch: Bool {
                    guard #available(iOS 11.0, *), let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first else { return false }
                    if UIDevice.current.orientation.isPortrait {
                        return window.safeAreaInsets.top >= 44
                    } else {
                        return window.safeAreaInsets.left > 0 || window.safeAreaInsets.right > 0
                    }
                }
            }
            

            【讨论】:

            • @NikhilMuskur 我刚刚在 iOS 14.1、Xcode 12.1 上尝试过 iPhone 8 Plus、iPhone 12 Pro 和 iPad Pro(11 英寸),效果很好。你的情况如何?
            • 在模拟器中一切正常,但当我在设备上运行时,isPortrait 属性始终为 false
            • @NikhilMuskur 你能更准确地描述你的情况吗?在什么设备上以及如何指定 isPortrait 属性始终为 false?
            • 调试时我发现UIDevice.current.orientation.isPortrait总是返回false,window.safeAreaInsets.left等于0。我在iPhone 11上测试过。奇怪的是,模拟器上的条件正常
            • 可以确认 UIVindow 的 rootViewController 不工作,稍后 - 工作
            【解决方案9】:
            extension UIDevice {
                var hasNotch: Bool {
                    let bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
                    return bottom > 0
                }
            }
            

            使用 'UIDevice.current.hasNotch' 将返回 true 或 false

            斯威夫特 5

            var hasNotch: Bool {
                let bottom = UIApplication.shared.delegate?.window??.safeAreaInsets.bottom ?? 0
                return bottom > 0
            }
            

            【讨论】:

            • 提倡你的代码是一个好习惯,考虑在你的答案中添加一些描述
            • 还请描述您的答案与现有的 8 个答案有何不同。
            猜你喜欢
            • 2022-01-15
            • 1970-01-01
            • 2012-09-18
            • 1970-01-01
            • 2012-11-03
            • 1970-01-01
            • 2012-03-27
            • 2013-02-19
            相关资源
            最近更新 更多