SwiftUI Gestures DragGesture

DragGesture

Track finger movement and update view position or state in response to a DragGesture.


Syntax

Drag: Attach DragGesture() and handle .onChanged/.onEnded.

Apply translation via .offset.


Drag to Move

Drag the label to move it around. Releasing snaps it back using a spring animation.

Example

Demo.swift

ContentView.swift

App.swift

import SwiftUI

struct DragDemo: View {
  @State private var offset: CGSize = .zero
  var body: some View {
Text("Drag me")
  .padding(12)
  .background(.blue.opacity(0.1))
  .cornerRadius(8)
  .offset(offset)
  .gesture(
    DragGesture()
      .onChanged { value in offset = value.translation }
      .onEnded { _ in withAnimation(.spring()) { offset = .zero } }
  )
} }

In the example above, the label is dragged and released.

The .onEnded handler snaps it back using a spring animation.


Constrain Drag Within Bounds

Clamp the drag translation so the view stays inside a container.

Example

Demo.swift

ContentView.swift

App.swift

import SwiftUI

struct DragBoundsDemo: View {
  @State private var offset: CGSize = .zero
  let limit: CGFloat = 120
  func clamp(_ v: CGFloat) -> CGFloat { min(max(v, -limit), limit) }
  var body: some View {
ZStack {
  RoundedRectangle(cornerRadius: 12)
    .stroke(.gray.opacity(0.4), lineWidth: 1)
    .frame(width: 280, height: 160)
  Circle()
    .fill(.blue.opacity(0.2))
    .frame(width: 44, height: 44)
    .offset(x: offset.width, y: offset.height)
    .gesture(
      DragGesture()
        .onChanged { value in
          offset = CGSize(width: clamp(value.translation.width), height: clamp(value.translation.height))
        }
        .onEnded { _ in withAnimation(.spring()) { offset = .zero } }
    )
}
.padding()
} }

In the example above, the circle is dragged and released.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *