How to check if Haptic Engine (UIFeedbackGenerator) is supported

后端 未结 6 955
星月不相逢
星月不相逢 2020-12-09 03:22

I am wondering how we could check if the new iOS 10 API UIFeebackGenerator is available on the current device. There are some more things we would need to check

相关标签:
6条回答
  • 2020-12-09 03:38

    There's some undocumented "private thing":

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

    it returns 2 for devices with haptic feedback - iPhone 7/7+ so you can easily use this to generate Haptic feedback:

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

    returns 1 for iPhone 6S, here's a fallback to generate taptic:

    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)
    

    and returns 0 for iPhone 6 or older devices. Since it's kind of undocumented thing it might block you during the review stage, although I was able to pass review and submit the app with such check.

    More details: http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/

    0 讨论(0)
  • 2020-12-09 03:39

    Based on Apple's UIFeedbackGenerator documentation, sounds like iOS does that for you.

    Note that calling these methods does not play haptics directly. Instead, it informs the system of the event. The system then determines whether to play the haptics based on the device, the application’s state, the amount of battery power remaining, and other factors.

    For example, haptic feedback is currently played only:

    On a device with a supported Taptic Engine (iPhone 7 and iPhone 7 Plus).

    When the app is running in the foreground.

    When the System Haptics setting is enabled.

    Even if you don't need to worry about check whether the device can do haptic feedback, you still need to ensure it's called only with iOS 10 or greater, so you could accomplish that with this:

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

    Here's a quick summary of the various haptic feedback options available in iOS 10.

    0 讨论(0)
  • 2020-12-09 03:48

    I made an extension to UIDevice without using the private API

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

    } and you use it like this :

    UIDevice.isHapticsSupported 
    

    returns true or false

    0 讨论(0)
  • 2020-12-09 03:53

    on iOS 13 you can check it in a very straightforward fashion. Following this documentation page, all you have to do is:

    iOS 13, Swift 5

    var supportsHaptics: Bool = false
    ...
    // Check if the device supports haptics.
    let hapticCapability = CHHapticEngine.capabilitiesForHardware()
    supportsHaptics = hapticCapability.supportsHaptics
    
    0 讨论(0)
  • 2020-12-09 03:54

    You know your device support Haptic vibration effect or not with below code,

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

    These methods seem to return:

    • 0 = Taptic not available

    • 1 = First generation (tested on an iPhone 6s) ... which does NOT support UINotificationFeedbackGenerator, etc.

    • 2= Second generation (tested on an iPhone 7) ... which does support it.

    it returns 2 for devices with haptic feedback - iPhone 7/7+ or higher so, you can easily use this to generate Haptic feedback

    0 讨论(0)
  • 2020-12-09 03:55

    This will work for iPhone 7 and Above.

     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
        }
    }
    
    0 讨论(0)
提交回复
热议问题