In my app I have a swipeable card view that can be dragged left or right.
When the user drags the card left or right, the card's horizontal offset is updated. When the user releases the drag, the card moves off the screen (either left or right, depending on the drag direction) or the card goes back to the initial position if the horizontal offset did not exceed the threshold.
It works well, but if the user touches the card view with another finger while dragging and then takes his/her fingers off screen, the card position freezes, and it doesn't either move off the screen or go back to the initial position. I debugged the code and it turns out that in that case the DragGesture().onEnded event does not fire.
I am looking for any hints on how I can detect this situation.
Here is the code:
If I had something like isTouchingScreen state, I would be able to solve this.
EDIT: Here is a minimal example where the problem manifests itself.
import SwiftUI
struct ComponentPlayground: View {
@State private var isDragging: Bool = false
@State private var horizontalOffset: CGFloat = .zero
var background: Color {
if abs(horizontalOffset) > 100 {
return horizontalOffset < 0 ? Color.red : Color.green
} else {
return Color.clear
}
}
var body: some View {
GeometryReader { geometry in
Color.white
.cornerRadius(15)
.shadow(color: Color.gray, radius: 5, x: 2, y: 2)
.overlay(background.cornerRadius(15))
.rotationEffect(.degrees(Double(horizontalOffset / 10)), anchor: .bottom)
.offset(x: horizontalOffset, y: 0)
.gesture(
DragGesture()
.onChanged { gesture in
self.isDragging = true
self.horizontalOffset = gesture.translation.width
}
.onEnded { gesture in
self.isDragging = false
if abs(horizontalOffset) > 100 {
withAnimation {
self.horizontalOffset *= 5
}
} else {
withAnimation {
self.horizontalOffset = .zero
}
}
}
)
.frame(width: 300, height: 500)
}
}
}
struct ComponentPlayground_Previews: PreviewProvider {
static var previews: some View {
VStack {
Spacer()
HStack(alignment: .center) {
ComponentPlayground()
}
.frame(width: 300, height: 500)
Spacer()
}
}
}
