如何检查是否支持触觉引擎(UIFeedbackGenerator)

27

我想知道如何检查当前设备是否支持新的iOS 10 API UIFeebackGenerator。还有其他一些需要检查的事项:

  1. 设备需要运行iOS 10.0或更高版本
  2. 设备需要是iPhone 7或更高版本
  3. 触觉引擎需要在设置中打开

第一和第二个检查可以使用#available(iOS 10, *)语句和一个(hacky)设备检测来实现,但后者似乎无法检查。

有人知道解决方案吗?或者我们需要为此提交苹果Radar。谢谢!

6个回答

21

有一些未记录的“私有事项”:

UIDevice.currentDevice().valueForKey("_feedbackSupportLevel");

若设备支持触觉反馈,如 iPhone 7/7+,返回值为2,因此您可以使用此代码轻松生成触觉反馈:

let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.prepare()
generator.impactOccurred()

iPhone 6S返回1,这里提供一个备选方案来生成触觉反馈:

import AudioToolbox

AudioServicesPlaySystemSound(1519) // Actuate `Peek` feedback (weak boom)
AudioServicesPlaySystemSound(1520) // Actuate `Pop` feedback (strong boom)
AudioServicesPlaySystemSound(1521) // Actuate `Nope` feedback (series of three weak booms)

对于iPhone 6或更早的设备,它会返回0。由于这是一种不太被记录的事情,在审核阶段可能会阻碍您,尽管我能够通过此类检查进行审核并提交应用。

更多细节请参见:http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/


仍然无法在我的iPhoneSE2015 iOS 13.4.1上振动。代码运行没有错误。 - Curtis

18

iOS 13开始,您可以以非常简单的方式检查它。根据文档页面,您需要做的就是:

import CoreHaptics

var supportsHaptics: Bool = false
...
// Check if the device supports haptics.
let hapticCapability = CHHapticEngine.capabilitiesForHardware()
supportsHaptics = hapticCapability.supportsHaptics

文档:准备您的应用程序播放触觉反馈


15

根据苹果的UIFeedbackGenerator文档, iOS似乎会为您完成此操作。

请注意,调用这些方法并不直接播放触觉反馈。相反,它通知系统事件的发生。 然后系统根据设备、应用程序状态、剩余电量和其他因素决定是否播放触觉反馈。

例如,触觉反馈目前仅在以下情况下播放:

支持触觉引擎的设备上(iPhone 7和iPhone 7 Plus)。

当应用程序在前台运行时。

启用系统触觉设置时。

即使您不需要担心设备是否可以进行触觉反馈,您仍然需要确保它仅在iOS 10或更高版本中调用,因此您可以通过以下方式实现:

    if #available(iOS 10,*) {
        // your haptic feedback method
    }

这里是iOS 10中可用的不同触觉反馈选项的快速概述。


12
如果触觉引擎不可用,你希望返回使用旧的AudioServicesPlaySystemSound吗? - Daniel Larsson
@DanielLarsson 这可能会有所帮助。您需要在版本10之前检查iOS。http://nshipster.com/swift-system-version-checking/ - Adrian
1
@Adrian 刚刚在 iOS 9 上测试了一下,似乎它什么也没做(没有让应用崩溃)。 - Idan

5

我创建了一个扩展 UIDevice 的功能,没有使用私有API。

extension UIDevice {
    
        static var isHapticsSupported : Bool {
            let feedback = UIImpactFeedbackGenerator(style: .heavy)
            feedback.prepare()
            return feedback.description.hasSuffix("Heavy>")
        }
    }

您可以这样使用它:
UIDevice.isHapticsSupported 

返回truefalse


1
这对我不起作用。在iPad上,它返回'true',但iPad不支持触觉反馈。 - Ailton Vieira Pinto Filho

2
您可以使用以下代码来检查您的设备是否支持触觉震动效果:
UIDevice.currentDevice().valueForKey("_feedbackSupportLevel");

这些方法似乎返回:
  • 0 = 触觉不可用

  • 1 = 第一代(在 iPhone 6s 上测试)...不支持 UINotificationFeedbackGenerator 等。

  • 2 = 第二代(在 iPhone 7 上测试)...支持它。
对于具有触觉反馈的设备,如 iPhone 7/7+ 或更高版本,它将返回 2,因此您可以轻松使用它来生成触觉反馈。

1
抱歉,但那是一个私有API,除非混淆,否则会导致拒绝。但对于内部应用程序来说,这是一个可用的解决方案! - Hans Knöchel
使用这些可能会导致您的应用在App Store的应用审核中被苹果拒绝,但目前似乎没有其他方法。 - Ashish

0

这将适用于 iPhone 7 及以上版本。

 var count = 0

 override func viewDidLoad() {
    super.viewDidLoad()

    let myButton = UIButton(frame: CGRect(x: 0, y: 100, width: 100, height: 50))
    myButton.setTitleColor(UIColor.green, for: .normal)
    myButton.setTitle("Press ME", for: .normal)
    myButton.addTarget(self, action: #selector(myButtonTapped), for: .touchUpInside)
    self.view.addSubview(myButton)

}

@objc func myButtonTapped() {
    count += 1
    print("Count \(count)")

    switch count {
    case 1:
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.error)

    case 2:
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.success)

    case 3:
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.warning)

    case 4:
        let generator = UIImpactFeedbackGenerator(style: .light)
        generator.impactOccurred()

    case 5:
        let generator = UIImpactFeedbackGenerator(style: .medium)
        generator.impactOccurred()

    case 6:
        let generator = UIImpactFeedbackGenerator(style: .heavy)
        generator.impactOccurred()

    default:
        let generator = UISelectionFeedbackGenerator()
        generator.selectionChanged()
        count = 0
    }
}

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