
Responding to gestures: Dragging
Learn how to implement drag gestures in SwiftUI to create fluid and intuitive draggable interface elements.
In SwiftUI, if you need to generate a drag gesture that invokes an action based on drag change events, use the DragGesture
structure.
@State var isBeingDragged = false
var draggingGesture: some Gesture {
DragGesture()
.onChanged { _ in self.isBeingDragged = true }
.onEnded { _ in self.isBeingDragged = false }
}
The onChanged(_:)
and onEnded(_:)
modifiers allow you to control what happens when the user performs the gesture and what happens once it stops.
When initializing a drag gesture object, you can use the DragGesture(minimumDistance:coordinateSpace:)
initializer to define the smallest drag distance for the gesture to be completed, with the minimumDistance
property, and in which coordinate space the gesture receives location values, with the coordinateSpace
property.
struct DraggingPlaygroundView: View {
let circleSize: CGFloat = 75
@State var isDragging = false
@State var currentPosition: CGPoint = .zero
var draggingObject: some Gesture {
DragGesture(minimumDistance: 1, coordinateSpace: .local)
.onChanged { gesture in
self.isDragging = true
self.currentPosition = gesture.location
}
.onEnded { _ in self.isDragging = false }
}
var body: some View {
Circle()
.fill(Color.blue)
.shadow(color: .primary, radius: isDragging ? 3 : 0, x: 0, y: isDragging ? 5 : 0)
.frame(width: circleSize, height: circleSize, alignment: .center)
.position(currentPosition)
.gesture(draggingObject)
.onAppear {
setupView()
}
}
private func setupView() {
let initialX = UIScreen.main.bounds.width / 2
let initialY = UIScreen.main.bounds.height / 2
currentPosition = CGPoint(x: initialX, y: initialY)
}
}
0:00
/0:10