Codakuma
iOS apps and more

Adding haptic feedback to buttons in SwiftUI

20 Jan 2021

Haptic feedback is a huge part of iOS and many apps use it well to add subtle feedback to certain actions.

Many SwiftUI elements have haptic feedback built in already. For example, when you drag your finger over the options in a Menu, you’ll feel a subtle tap. When you switch a Toggle on and off you’ll feel a firmer tap.

Other elements like buttons don’t have any built-in haptics, so we need to add them ourselves. Hacking With Swift has a great tutorial about how to do this, which I’ve based this post on. We’ll create an extension for View so that we can trigger haptic feedback with one line of code. It’s very short because iOS has an excellent, succinct API for triggering basic haptics.

One caveat is that this won’t work on Buttons, because it relies on onTapGesture, which doesn’t seem to work on Button. I’ll show how to add haptic feedback to a button later in this post.

import SwiftUI

extension View {

  func hapticFeedbackOnTap(style: UIImpactFeedbackGenerator.FeedbackStyle = .light) -> some View {
    self.onTapGesture {
      let impact = UIImpactFeedbackGenerator(style: style)
      impact.impactOccurred()
    }
  }

}

To use it, just add it to any view:

// Light feedback when some text is tapped.
Text("Tap me and I'll tap you back")
  .hapticFeedbackOnTap()


// Rigid feedback when a menu is opened.
Menu {
  Button(action: { }) {
    Text("Press me")
  }
  Button(action: {  }) {
    Text("Press me too")
  }
} label: {
    Text("Open menu")
}
.hapticFeedbackOnTap(style: .rigid)

As I mentioned earlier, onTapGesture doesn’t work on Button, so this won’t work. For Buttons, you’ll need to call the haptic function from the Button’s action:

Button(action: {
  let impact = UIImpactFeedbackGenerator(style: style)
  impact.impactOccurred()
}) {
  Text("Press me")
}

Feedback styles

The function takes an optional argument of type UIImpactFeedbackGenerator.FeedbackStyle. There are several possible values, each giving a different haptic sensation.

Here’s a handy code snippet from Harry Harrison you can run on your phone to try out the different sensations.

More advanced haptics

For more complex haptic feedback, iOS offers the fantastic CoreHaptics module. It’s outside the scope of this post, but as always Hacking With Swift has a really thorough tutorial about how to use it.