🦋
SwiftUI: DragGestureは2本指ドラッグするとonEnded()が不発
DragGesture
を適用したViewにまず1本指で触れてドラッグした後、触れる指をもう一本追加するとonEnded()
が不発のままDragGesture
がキャンセルされます。
struct TouchView: View {
let onTouchDownHandler: () -> Void
let onTouchUpHandler: () -> Void
var body: some View {
Rectangle()
.frame(width: 100, height: 40)
.gesture(
DragGesture(minimumDistance: 0.0, coordinateSpace: .local)
.onChanged { _ in
onTouchDownHandler()
}
.onEnded { _ in
onTouchUpHandler()
}
)
}
}
なので、上記のようなViewではonTouchUpHandler()
が呼ばれず、意図しない挙動をする可能性があります。そこで、onEnded()
ではなくupdating()
を使うことで、キャンセルの場合も処理をハンドリングできます。
struct TouchView: View {
@GestureState var isGestureActive: Bool = false
let onTouchDownHandler: () -> Void
let onTouchUpHandler: () -> Void
var body: some View {
Rectangle()
.frame(width: 100, height: 40)
.gesture(
DragGesture(minimumDistance: 0.0, coordinateSpace: .local)
.onChanged { _ in
onTouchDownHandler()
}
.updating($isGestureActive) { _, state, _ in
state = true
}
)
.onChange(of: isGestureActive) { newValue in
if !newValue {
onTouchUpHandler()
}
}
}
}
Discussion