检查 iOS9 设备是否支持并启用 3D 触摸

Check if 3D touch is supported and enabled on the iOS9 device

我试图访问特征集合并检查 "forceTouchCapability",但 "forceTouchCapability" 只是检查设备是否为 iOS 9.0 或更高版本。

因此,这意味着在具有 iOS 9 的任何设备上,强制触摸都是 'available'。我需要一种方法来检查用户设备是否真正支持 3D 触摸 (iPhone 6s),并且我需要确保在辅助功能设置中实际启用了 3D 触摸选项。

我不小心将 forceTouchCapability 转换为 BOOL(将其用作我的方法的 return 值,该方法设置为 return 布尔值)。我需要检查 forceTouchCapability 是否等于 UIForceTouchCapabilityAvailable.

而不是:

return [[MyView traitCollection] forceTouchCapability];

我需要:

return [[MyView traitCollection] forceTouchCapability] == UIForceTouchCapabilityAvailable;

如果您在 UIViewController 中实现它,时机很重要。签入 viewDidLoad 将 return Unknown 将在生命周期的后期 return Available

- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection {
    [self checkForForceTouch];
}

- (void)checkForForceTouch {
    if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] &&
        self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
        NSLog(@"Force touch found");
    }
}

有时我们只想立即同步获得 forceTouchCapability 值,不想等待 traitCollectionDidChange: 事件。在那种情况下,我们可以像这样使用非常愚蠢的函数:

public func forceTouchCapability() -> UIForceTouchCapability {
    return UIApplication.sharedApplication().keyWindow?.rootViewController?.traitCollection.forceTouchCapability ?? .Unknown
}
if ([MyView respondsToSelector:@selector(traitCollection)] &&
    [MyView.traitCollection respondsToSelector:@selector(forceTouchCapability)] &&
    MyView.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
        return YES;
    }

我的观点是,如果你也支持 iOS 7iOS 8,请记住检查两个条件:[MyView respondsToSelector:@selector(traitCollection)][MyView.traitCollection respondsToSelector:@selector(forceTouchCapability)].

如果您保留第一次检查,该应用程序在 iOS 7 上运行良好,但在 iOS 8 上崩溃。 基本上,Apple 在 iOS 8 中引入了 traitCollection 属性,但仅在 iOS 9.

中添加了 forceTouchCapability 属性

来自UITraitCollection.h:

@property (nonatomic, readonly) UITraitCollection *traitCollection NS_AVAILABLE_IOS(8_0);

@property (nonatomic, readonly) UIForceTouchCapability forceTouchCapability NS_AVAILABLE_IOS(9_0);

PS:在应用程序开始在 App Store 上崩溃后,通过艰难的方式学习了它。

Swift 4.0 和 4.1.

import UIKit

class ViewController: UIViewController {
     override func viewDidLoad() {
        super.viewDidLoad()
        // Check device supports feature
        if self.traitCollection.forceTouchCapability == .available {
        // Enable 3D Touch feature here
         } else {
        // Fall back to other non 3D feature
         }
      }
      override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        // Update the app's 3D Touch support
      if self.traitCollection.forceTouchCapability == .available {
          // Enable 3D Touch feature here
      } else {
          // Fall back to other non 3D feature
      }
    }
  }

关注 Valentin Shergin,更新为 swift 4.2 如果您需要同步调用:

func forceTouchCapability() -> UIForceTouchCapability {
    return UIApplication.shared.keyWindow?.rootViewController?.traitCollection.forceTouchCapability ?? .unknown
}


func hasForceTouchCapability() -> Bool {
    return forceTouchCapability() == .available
}