Choose the right feedback

In the specific UIFeedbackGenerator is an abstract superclass that we cannot use directly, we have to choose between 3 concrete subclasses, each one with a specific destination of use.

UISelectionFeedbackGenerator

Provide this feedback when user is changing selection through a series of discrete values, for instance Apple is using it when moving through a picker like UIDatePicker.

You can use it on multiple selection table views and collection views, when implementing a custom segmented control or when any selection is changing.

UIImpactFeedbackGenerator

This feedback is intended to be used to simulate a physical impact with taptic engine.

Use it when an UI element snaps into place or when some elements collide.

it has 3 levels of intensity that you have to pass as init parameter: light, medium and heavy. Apple recommend to choose intensity based on UI element size.

I’m also using it in a custom 3D touch gesture recognizer (here on GitHub and my Medium post) to provide feedback about successful gesture, with medium style.

UINotificationFeedbackGenerator

This is the most complete feedback generator. You should use it to communicate the result of a task or of an action.

Similar to ImpactFeedback it accept a parameter but this time is not ini init method but when running the feeedback. Style this time is not about intensity but refers to notification action result: success, warning or error. Choose the one that represent the result of the action the user has ended.

Implementation

UIFeedbackGenerator is very simple to integrate in your app.

Is available since iOS 10 and unless you’re supporting previous iOS versions you don’t have to check availability, otherwise:

if #available(iOS 10, *) {

//UIFeedbackGenerator code block

}

Or a cleaner swifty way:

guard #available(iOS 10, *) else {

return

}

//UIFeedbackGenerator code block

Now you’re ready to initialize the concrete class you choose from the 3 available, and make sure to choose the one that fit user action.

let feedbackGenerator = UISelectionFeedbackGenerator.init()

//or

let feedbackGenerator = UIImpactFeedbackGenerator(style: .medium)

//or

let feedbackGenerator = UINotificationFeedbackGenerator()

Once the feedbackGenerator is initialized is recommended but not mandatory to prepare the Taptic Engine. When you prepare the engine it will stay in an prepared state just for a few seconds so don’t prepare it too early. The release of the prepared feedback will be more performant and responsive if you want to be tempestive and sync it with a sound or with a visual effect.

Discover more about prepare method on Apple docs.

feedbackGenerator.prepare()

Now we can trigger the feedback.

Note that the signature changes for each concrete subclass:

//UISelectionFeedbackGenerator

feedbackGenerator.selectionChanged() //UIImpactFeedbackGenerator

feedbackGenerator.impactOccurred() //UINotificationFeedbackGenerator

feedbackGenerator.notificationOccurred(.success)

(Optional) Remove any reference to the feedback generator from your code or if you have a global or local variable set it to nil. This step will bring Taptic Engine to idle status and will free it for other uses.

feedbackGenerator = nil

Safe by design

UIFeedbackGenerator is safe to implement. You just need to have it on iOS 10+ and everything is handled by iOS.

If you use it on a device that doesn’t have haptic feedback support (because is an old device or has the option disabled in system preferences) you don’t have to do anything, simply it won’t work but will not broke your app.

References and further details