如何判断当前运行的 Apple Watch 尺寸/尺寸是 38 毫米还是 42 毫米?

Posted

技术标签:

【中文标题】如何判断当前运行的 Apple Watch 尺寸/尺寸是 38 毫米还是 42 毫米?【英文标题】:How to tell if current running Apple Watch size/dimension is 38mm or 42mm? 【发布时间】:2015-04-09 02:38:54 【问题描述】:

我们知道 Apple Watch 有两种屏幕尺寸:38 毫米和 42 毫米。 WKInterfaceDevice 类提供了一个名为 screenBounds 的可读属性。我为WKInterfaceDevice写了一个扩展,试图添加一个方法来检测当前设备类型。

import WatchKit

enum WatchResolution 

    case Watch38mm, Watch42mm


extension WKInterfaceDevice 

    class func currentResolution() -> WatchResolution 

        let watch38mmRect = CGRectMake(0.0, 0.0, 136.0, 170.0)
        let watch42mmRect = CGRectMake(0.0, 0.0, 156.0, 195.0)

        let currentBounds = WKInterfaceDevice.currentDevice().screenBounds

        if CGRectEqualToRect(currentBounds, watch38mmRect) 

            return WatchResolution.Watch38mm
         else 

            return WatchResolution.Watch42mm
        
    

这是检测 Apple Watch 尺寸的正确方法吗? Apple 文档中是否还有我遗漏的方法?

【问题讨论】:

【参考方案1】:

您的代码看起来不错,但有一些小问题:

您没有针对“未知”屏幕尺寸(未来可能发布)的案例 您正在使用 CGRectMake,但在 Swift 中您应该使用 CGRect 初始化程序 您使用的是CGRectEqualToRect,但在 Swift 中您可以只使用==switch 您明确返回 WatchResolution 枚举,但您不需要明确 - Swift 会从您的方法签名中找出答案 您声明了 watch42mmRect,但没有将其用于任何用途

我会这样重写:

enum WatchResolution 
    case Watch38mm, Watch42mm, Unknown


extension WKInterfaceDevice 
    class func currentResolution() -> WatchResolution 
        let watch38mmRect = CGRect(x: 0, y: 0, width: 136, height: 170)
        let watch42mmRect = CGRect(x: 0, y: 0, width: 156, height: 195)

        let currentBounds = WKInterfaceDevice.currentDevice().screenBounds

        switch currentBounds 
        case watch38mmRect:
            return .Watch38mm
        case watch42mmRect:
            return .Watch42mm
        default:
            return .Unknown
        
    

【讨论】:

这太棒了!谢谢!【参考方案2】:

更新 Swift 4:

它包括新推出的手表分辨率:

enum WatchResolution 
    case Watch38mm, Watch40mm,Watch42mm,Watch44mm, Unknown  


extension WKInterfaceDevice 
class func currentResolution() -> WatchResolution 
    let watch38mmRect = CGRect(x: 0, y: 0, width: 136, height: 170)
    let watch40mmRect = CGRect(x: 0, y: 0, width: 162, height: 197)
    let watch42mmRect = CGRect(x: 0, y: 0, width: 156, height: 195)
    let watch44mmRect = CGRect(x: 0, y: 0, width: 184, height: 224)

    let currentBounds = WKInterfaceDevice.current().screenBounds

    switch currentBounds 
    case watch38mmRect:
        return .Watch38mm
    case watch40mmRect:
        return .Watch40mm
    case watch42mmRect:
        return .Watch42mm
    case watch44mmRect:
        return .Watch44mm
    default:
        return .Unknown
    
   

用法

let resol = WKInterfaceDevice.currentResolution()
    switch resol 
    case .Watch38mm, .Watch42mm:
        // Do Something
    case .Watch40mm, .Watch44mm:
        // Do Something
    default:
        // Do Something
    

参考链接: Apple Developer Watch Interface Link

希望对您有所帮助....

谢谢

【讨论】:

【参考方案3】:

这就是我正在做的:

enum WatchModel 
    case w38, w40, w42, w44, unknown


extension WKInterfaceDevice 

    static var currentWatchModel: WatchModel 
        switch WKInterfaceDevice.current().screenBounds.size 
        case CGSize(width: 136, height: 170):
            return .w38
        case CGSize(width: 162, height: 197):
            return .w40
        case CGSize(width: 156, height: 195):
            return .w42
        case CGSize(width: 184, height: 224):
            return .w44
        default:
            return .unknown
    
  

【讨论】:

【参考方案4】:

您的方法看起来不错,没有任何问题。另一种解决方案是使用 WKInterfaceController 的 contentFrame 属性。如果宽度是 312(156)像素,那么它的 42 毫米,否则是 38 毫米。

【讨论】:

看看它在哪里说“这个矩形可能与屏幕边界不同。”?但是 OP 正在尝试获取屏幕边界。 我猜是因为身高。可能会因内容而异。所以这就是我说宽度的原因。【参考方案5】:
CGRect rect = [WKInterfaceDevice currentDevice].screenBounds;
if (rect.size.height == 195.0) 
    // Apple Watch 42mm
else if (rect.size.height == 170.0)
    // Apple Watch 38mm 

【讨论】:

请始终在您的回答中添加更多细节。【参考方案6】:

在带有 ios 9 的 xCode 7 和真实设备上检查 screenBounds 似乎不再起作用,Watch 38mm 返回的手表尺寸始终为 156x195。

我的(不好的)替代方法是根据视图结构检查视图控制器 contentFrame 的宽度或高度

【讨论】:

发现了同样的问题。似乎是苹果的错误。【参考方案7】:

以上所有解决方案都可以正常工作。除了 screenBounds ([[WKInterfaceDevice currentDevice] screenBounds]),还可以检查 screenScale ([[WKInterfaceDevice currentDevice] screenScale])。在这个意义上,实际大小将是 screenBounds * screenScale。

更多参考:https://developer.apple.com/watch/human-interface-guidelines/specifications/

【讨论】:

【参考方案8】:

对于 Swift 4 更短的示例:

enum WatchType 
    case watch38mm, watch42mm


extension WKInterfaceDevice 

    class var currentResolution: WatchType 
        // Apple Watch 38mm 136x170 - 42mm 156x195
        return WKInterfaceDevice.current().screenBounds.width == 136 ? .watch38mm : .watch42mm
    


【讨论】:

【参考方案9】:

Swift 5 版本的@Aaron Brager 答案(+ 支持新的 Apple Watch)。

enum WatchResolution 
case Watch38mm, Watch40mm, Watch42mm, Watch44mm, Unknown


extension WKInterfaceDevice 

class func currentResolution() -> WatchResolution 

    let watch38mmRect = CGRect(x: 0, y: 0, width: 136, height: 170)
    let watch40mmRect = CGRect(x: 0, y: 0, width: 162, height: 197)
    let watch42mmRect = CGRect(x: 0, y: 0, width: 156, height: 195)
    let watch44mmRect = CGRect(x: 0, y: 0, width: 184, height: 224)

    let currentBounds = WKInterfaceDevice.current().screenBounds

    switch currentBounds 
    case watch38mmRect:
        return .Watch38mm
    case watch40mmRect:
        return .Watch40mm
    case watch42mmRect:
        return .Watch42mm
    case watch44mmRect:
        return .Watch44mm
    default:
        return .Unknown
    




/*
 all resolutions
 40mm: 394×324
 44mm: 448×368
 38mm: 340×272
 42mm: 390×312
 */

【讨论】:

【参考方案10】:

我这样做是为了避免自己过多依赖当前尺寸和未来证明

public enum WatchSizeClass 
    case small, regular


public extension WKInterfaceDevice 
    static var currentWatchSizeClass: WatchSizeClass 
        if WKInterfaceDevice.current().screenBounds.size.width < 150 
            return .small
         else 
            return .regular
        
    

目前,.small 仅返回 38mm。

【讨论】:

以上是关于如何判断当前运行的 Apple Watch 尺寸/尺寸是 38 毫米还是 42 毫米?的主要内容,如果未能解决你的问题,请参考以下文章