A dragging motion that invokes an action as the drag-event sequence changes.
Apple Documentation
In this tutorial, we will learn what Drag Gesture in SwiftUI is:
- .onChanged.
- .updating.
- .onEnded.
- limit scrolling.
Prerequisites
To follow along with this tutorial, you’ll need some basic knowledge about:
- Basic with Swift.
- Xcode 11 and above
.onChanged
onChanged
changes the value of the position as you drag.
First, create a variable to save the size. With the variable below, the object is placed at coordinates where x and y are 50
1 2 | @State private var rectPosition = CGPoint(x: 50, y: 50) |
When the rectangle moves, you will change the rectPosition
1 2 3 4 5 6 7 8 9 10 | VStack { RoundedRectangle(cornerRadius: 4.0) .fill(Color.green) .frame(width: 100, height: 100) .position(rectPosition) .gesture(DragGesture().onChanged({ value in self.rectPosition = value.location })) } |
As a result you will have a moving rectangle as shown below.
.updating
You can tell if the user is pulling or not by getting the state
. First, create a GestureState
to keep it dragged.
1 2 | @GestureState private var isDragging = false |
Here, you cannot update isDragging
as it is read-only. However, you can update the state
then it will update isDragging
.
1 2 3 4 5 6 | .gesture(DragGesture().onChanged({ value in self.rectPosition = value.location }).updating($isDragging, body: { (value, state, trans) in state = true })) |
.onEnded
In many cases, you only want to take the action after the user has finished dragging the object. First, create a variable to know if the user finished dragging or not.
1 2 | @State private var isEnded = false |
Use the same code as above and tweak it a bit, for the color to change if x is less than 120.
1 2 3 4 5 6 7 8 9 10 11 12 | VStack { RoundedRectangle(cornerRadius: 4.0) .fill(isEnded ? Color.red : Color.green) .frame(width: 100, height: 100) .position(rectPosition) .gesture(DragGesture().onChanged({ value in self.rectPosition = value.location }).onEnded({ value in self.isEnded = value.location.x < 120 })) } |
Result:
Limit horizontal scrolling
1 2 3 4 | .gesture(DragGesture().onChanged({ value in self.rectPosition = CGPoint(x: value.location.x, y: 50) })) |
If you just want it to scroll vertically, just change the y value.