Encountering a problem in some hobby code in which a long-press appear to be misbehaving (that is, the previous action stopped happening ). I took the sample Apple code and started playing which revealed an anomaly (in my mind).
The anomaly is that if the gesture fails, then, whilst the underlying GestureState var is changed, neither the .onChange nor .onEnded modifiers are called. Similarly, .onEnded is ONLY invoked when the gesture succeeds. In a similar anomalous behavior, long-press, in isolation, appears to be detected and triggered, the instant the click happens. Which to me is contrary to the concept of a long-Press.
My sample code is below (modified Apple sample with print statements to track the sequence of events). If you click and hold the click until the duration expires then the associated actions occur as you expect, however, if you click, hold, and drag beyond the distance parameter or simply click and release, then the only place for detecting that failure is in the view that the gesture is attached to.
Does anyone know of a way of detecting a long-press failure?
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
LongPressGestureView()
}
.padding()
}
}
struct LongPressGestureView: View {
@GestureState var isDetectingLongPress = false
@State var completedLongPress = false
@State var scaleFactor = 1.0
var longPress: some Gesture {
LongPressGesture(minimumDuration: 4, maximumDistance: 100)
.updating($isDetectingLongPress) { currentState, gestureState,
transaction in
print("Gesture updating detected currentState: \(currentState)")
print("Gesture updating: saw state of completedLongPress: \(completedLongPress)")
gestureState = currentState
transaction.animation = Animation.easeIn(duration: 2.0)
}
.onChanged() { state in
print("Gesture onChange: saw state of isDetectingLongPress: \(state)")
print("Gesture onChange: saw state of completedLongPress: \(completedLongPress)")
}
.onEnded { finished in
print("Gesture onEnded detected completed: \(self.completedLongPress)")
self.completedLongPress = finished
}
}
var body: some View {
Circle()
.scale(scaleFactor)
.fill(self.isDetectingLongPress ?
Color.red :
(self.completedLongPress ? Color.green : Color.blue))
.frame(width: 100, height: 100, alignment: .center)
.gesture(longPress)
.onChange(of: self.isDetectingLongPress) {newState in
print("View: onChange isDetectingLongPress: \(newState)")
print("View: onChange isDetectingLongPress completedLongPress: \(completedLongPress)")
scaleFactor = newState ? 3.0 : 1.0
}
.onChange(of: self.completedLongPress) { state in
print("View: onChange completedLongPress isDetectingLongPress: \(isDetectingLongPress)")
print("View: onChange completedLongPress: \(completedLongPress)")
if (state) {
scaleFactor = 1.0
completedLongPress = false
}
}
.animation(.easeInOut(duration: 1.0), value: scaleFactor)
}
}