检查 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 7 和 iOS 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
}
我试图访问特征集合并检查 "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 7 和 iOS 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
}