Skip to content

Gestures in SwiftUI: Tap, Long Tap, Drag, Rotation

Gestures play a vital role in creating interactive and intuitive user interfaces. SwiftUI offers a variety of gesture recognizers that allow you to add touch and motion-based interactions to your apps easily. This tutorial will guide you through the basics of using gestures in SwiftUI with unique and interesting examples suitable for developers of all levels.

Introduction to Gestures in SwiftUI

SwiftUI provides several built-in gestures such as tap, drag, long press, and rotation. You can attach these gestures to any view using the .gesture modifier. Let’s explore each of these gestures with practical examples.

Tap Gesture

The tap gesture is one of the simplest and most commonly used gestures. It detects a single or multiple taps on a view.

Example: Using Tap Gesture

import SwiftUI

struct TapGestureView: View {
    @State private var message = "Tap on the circle"

    var body: some View {
        VStack {
            Circle()
                .fill(Color.blue)
                .frame(width: 100, height: 100)
                .onTapGesture {
                    message = "Circle tapped!"
                }
            Text(message)
                .padding()
        }
    }
}

In this example, a Circle view changes the message displayed in the Text view when tapped.

Long Press Gesture

The long press gesture recognizes when a user presses and holds on a view for a specified duration.

Example: Using Long Press Gesture

import SwiftUI

struct LongPressGestureView: View {
    @State private var isPressed = false

    var body: some View {
        Circle()
            .fill(isPressed ? Color.red : Color.green)
            .frame(width: 100, height: 100)
            .onLongPressGesture {
                isPressed.toggle()
            }
    }
}

In this example, the color of the Circle view toggles between red and green when long pressed.

Drag Gesture

The drag gesture allows users to drag views across the screen.

Example: Using Drag Gesture

import SwiftUI

struct DragGestureView: View {
    @State private var offset = CGSize.zero
    @State private var startLocation = CGSize.zero

    var body: some View {
        Circle()
            .fill(Color.purple)
            .frame(width: 100, height: 100)
            .offset(x: offset.width + startLocation.width, y: offset.height + startLocation.height)
            .gesture(
                DragGesture()
                    .onChanged { gesture in
                        offset = CGSize(width: gesture.translation.width + startLocation.width,
                                        height: gesture.translation.height + startLocation.height)
                    }
                    .onEnded { gesture in
                        startLocation = CGSize(width: offset.width, height: offset.height)
                        offset = .zero
                    }
            )
    }
}

In this example, a Circle view can be dragged around the screen.

Explanation
  1. State Variables: We use offset to track the current drag offset and startLocation to remember the view’s position after each drag.
  2. onChanged: During the drag, we update offset by adding the current gesture translation to the start location.
  3. onEnded: When the drag ends, we update startLocation to the new position and reset offset to zero for the next drag.

Rotation Gesture

The rotation gesture detects rotation interactions and can be used to rotate views.

Example: Using Rotation Gesture

import SwiftUI

struct RotationGestureView: View {
    @State private var rotation: Angle = .zero
    @State private var lastRotation: Angle = .zero

    var body: some View {
        Rectangle()
            .fill(Color.orange)
            .frame(width: 200, height: 200)
            .rotationEffect(rotation + lastRotation)
            .gesture(
                RotationGesture()
                    .onChanged { angle in
                        rotation = angle
                    }
                    .onEnded { angle in
                        lastRotation += rotation
                        rotation = .zero
                    }
            )
    }
}
Explanation
  1. State Variables: We use rotation to track the current rotation during the gesture and lastRotation to remember the accumulated rotation after each gesture.
  2. onChanged: During the rotation, we update rotation to the current gesture’s angle.
  3. onEnded: When the rotation ends, we add the current rotation to lastRotation and reset rotation to zero for the next gesture.

Combining Gestures

SwiftUI allows you to combine multiple gestures on a single view using the .simultaneousGesture modifier.

Example: Combining Tap and Long Press Gestures

struct CombinedGestureView: View {
    @State private var message = "Tap or Long Press"

    var body: some View {
        VStack {
            Circle()
                .fill(Color.blue)
                .frame(width: 100, height: 100)
                .onTapGesture {
                    message = "Circle tapped!"
                }
                .simultaneousGesture(
                    LongPressGesture()
                        .onEnded { _ in
                            message = "Circle long pressed!"
                        }
                )
            Text(message)
                .padding()
        }
    }
}
Explanation
  1. State Variable: We use a @State variable message to display the current gesture action.
  2. Circle View: We create a Circle view with a blue fill, setting its frame to 100×100 points.
  3. Tap Gesture: We use .onTapGesture to detect tap gestures on the Circle view. When the Circle is tapped, it updates the message to “Circle tapped!”.
  4. Long Press Gesture: We use .simultaneousGesture to combine a LongPressGesture with the tap gesture. When the Circle is long-pressed, it updates the message to “Circle long pressed!”.
  5. Text View: We display the message in a Text view below the Circle, which updates based on the detected gesture.
How It Works
  • Tap Gesture: When you tap on the Circle, the onTapGesture modifier is triggered, updating the message to “Circle tapped!”.
  • Long Press Gesture: When you long press on the Circle, the onEnded closure of the LongPressGesture is triggered, updating the message to “Circle long pressed!”.

In this example, the Circle view can detect both tap and long press gestures, updating the message accordingly.

Conclusion

SwiftUI gestures provide a powerful way to create interactive and responsive user interfaces. By understanding and using these gestures, you can enhance the user experience in your apps.

 

Back To Top