检查iOS9设备是否支持并启用了3D Touch功能。

14

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

这意味着在任何iOS 9设备上,都可使用触压功能。我需要一种方法来检查用户设备(iPhone 6s)是否实际支持3D Touch,并确保启用辅助功能设置中的3D Touch选项。


这是个坏消息 - 你在9.1测试版上试过了吗? - Rhythmic Fistman
不,我们正在为即将发布的应用程序添加3D Touch功能,因此我们的目标是9.0。使用Xcode 7.0。 - Prodigga
我们有三个设备 - 一个iPad Air 1(没有3D Touch,运行iOS 9.0),iPhone 6(没有3D Touch,运行iOS 8.3),iPhone 6s(3D Touch,运行iOS 9.0)。 - Prodigga
我只是想指出返回值不是 BOOL - rmaddy
业余错误 :-) 我自己回答了我的问题。 - Prodigga
显示剩余6条评论
6个回答

24

我不小心将forceTouchCapability强制转换为BOOL(将其作为返回布尔值的方法的返回值使用)。我需要检查forceTouchCapability是否等于UIForceTouchCapabilityAvailable

改为:

return [[MyView traitCollection] forceTouchCapability];

我需要:

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

请注意,如果您的应用程序支持iOS 8.x或更早版本以及iOS 9,则需要适当保护此代码。 - rmaddy
好的!谢谢,已经完成 :) 已经遇到过那个问题了,呵呵。 - Prodigga
Swift版本 https://dev59.com/DJHea4cB1Zd3GeqPjwzo?lq=1 - Irfan Gul
@Prodigga 嘿,我没有3D Touch设备,我想问一下:虽然对于不支持3D Touch的设备它会返回“NotAvailable”,但是对于在设置中禁用了3D Touch的设备,它是否也会返回“NotAvailable”? - ShayanK

12

如果您在UIViewController中实现此操作,时间点很重要。在viewDidLoad中检查将返回Unknown,而在生命周期后期将返回Available

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

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

谢谢 - 这就是我的问题! - JimmyB
3D Touch在设置中被禁用,如何检查这个问题。 - Shohrab
@Shohrab 这个方法会自动检测到这个。 - saagarjha

3
有时,我们想要同步地立即获取forceTouchCapability的值,而不想等待traitCollectionDidChange:事件。在这种情况下,我们可以使用类似于以下的非常愚蠢的函数来实现:
public func forceTouchCapability() -> UIForceTouchCapability {
    return UIApplication.sharedApplication().keyWindow?.rootViewController?.traitCollection.forceTouchCapability ?? .Unknown
}

3
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 上崩溃。 基本上,苹果在 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);

注意:我是在应用程序开始在应用商店崩溃之后才艰难地学会了这一点。


0

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
      }
    }
  }

0

跟随 Valentin Shergin,如果您需要同步调用,则更新为 Swift 4.2:

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


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接