I want to detect where the drag gesture first began. I have a subview that is only 20 points wide. I add a Drag Gesture to the super view and want to move around this subview only if the drag gesture start location at the beginning of the gesture was within 20 points of the location of this subview. I do not want to add drag gesture to this subview as it has caused other problems in the code (reported in other SO questions and with no clean solution). So I try adding the Gesture to the superview instead.
I have tried the following code but it doesn't work as it doesn't detect when & where the gesture BEGAN.
DragGesture(minimumDistance: 0)
.updating($scrubberSeeking, body: { value, state, _ in
if abs(value.startLocation.x - scrubberOffset) > 20.0 {
state = false
return
}
state = true
})
.onChanged({ value in
if scrubberSeeking {
...
...
}
})
.onEnded { value in
}
To detect where the drag gesture first started,
try this approach storing the start of a drag into a var dragStartPosition
in .onChanged
.
Then resetting that var to nil in .onEnded
after completing any desired logic,
as shown in the example code:
struct ContentView: View {
@State private var isDragging = false
@State private var dragStartPosition: CGPoint?
var body: some View {
Circle()
.fill(isDragging ? Color.red : Color.blue)
.frame(width: 100, height: 100)
.gesture(
DragGesture(minimumDistance: 0)
.onChanged { value in
if dragStartPosition == nil {
dragStartPosition = value.startLocation
print("---> dragStartPosition is: \(dragStartPosition)")
isDragging = true
}
}
.onEnded { value in
if let startPosition = dragStartPosition {
print("------> startPosition was: \(startPosition)")
}
dragStartPosition = nil
isDragging = false
}
)
}
}
EDIT-1
code example to also drag the Circle
as well as answering the question of how to
detect where the drag gesture first started.
struct ContentView: View {
@State private var isDragging = false
@State private var dragStartPosition: CGPoint?
@State private var circlePos: CGPoint = CGPoint(x: 100, y: 100)
var body: some View {
Circle()
.fill(isDragging ? Color.red : Color.blue)
.frame(width: 100, height: 100)
.position(circlePos)
.gesture(
DragGesture(minimumDistance: 0)
.onChanged { value in
if dragStartPosition == nil {
dragStartPosition = value.startLocation
print("---> dragStartPosition is: \(dragStartPosition)")
isDragging = true
}
circlePos = value.location
}
.onEnded { value in
if let startPosition = dragStartPosition {
print("------> startPosition was: \(startPosition)")
}
dragStartPosition = nil
isDragging = false
}
)
}
}