Chapters

Hide chapters

SwiftUI Cookbook

Live Edition · iOS 16.4 · Swift 5.8.1 · Xcode 14.3.1

Exclusive Gestures in SwiftUI
Written by Team Kodeco

When creating engaging user interfaces, sometimes we want to provide multiple ways of interacting with our views. This can lead to ambiguity, as one gesture might interfere with another. Fortunately, SwiftUI provides an easy way to manage these situations through exclusive gestures.

An exclusive gesture is essentially a way of telling SwiftUI to prioritize one gesture over another. This might come in handy when you have overlapping gestures, where one should take precedence. Let’s illustrate this concept through a playful example.

Imagine an application where you can move a cute bird icon across the screen by dragging it around. Now, you want to add a double-tap gesture to make the bird return to its original position.

Here’s how you might implement this:

struct ContentView: View {
  @State private var dragOffset = CGSize.zero
  @State private var originalPosition = CGSize.zero

  var body: some View {
    let dragGesture = DragGesture()
      .onChanged { value in
        self.dragOffset = value.translation
      }
      .onEnded { _ in
        self.originalPosition = self.dragOffset
      }

    let doubleTapGesture = TapGesture(count: 2)
      .onEnded {
        self.dragOffset = .zero
      }

    return Image(systemName: "bird")
      .resizable()
      .scaledToFit()
      .frame(width: 100, height: 100)
      .offset(dragOffset)
      .gesture(
        doubleTapGesture.exclusively(before: dragGesture)
      )
      .animation(.easeInOut, value: dragOffset)
  }
}

Here’s what your preview should look like:

Use exclusively(before:) to prioritize gestures in SwiftUI.
Use exclusively(before:) to prioritize gestures in SwiftUI.

In this example, you have an image of a bird that the user can drag around. You have added a DragGesture to track the position of the bird as it’s dragged. However, you’ve also added a TapGesture that triggers when the bird is double-tapped, resetting its position.

The key here is the exclusively(before:) modifier. This tells SwiftUI that when it recognizes a double-tap, it should not also recognize a drag. In other words, the double-tap gesture takes exclusive priority over the drag gesture.

This simple tool allows us to resolve potential conflicts between gestures, making our user interfaces more predictable and enjoyable to use. Now, go ahead and experiment with these gestures in your own SwiftUI projects!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.