Animation issue when Long-Press is canceled - SwiftUI, iOS 14.5

339 Views Asked by At

I'm still learning and trying to understand the ins and outs of swiftUI. Currently, I focus on understanding gestures and animations and here is an issue that seems unsolvable at my experience level:

The problem: I experience unexpected behavior if the longPressGesture is canceled, eg. lifting the finger before the minimumDuration of the longPress is exceeded.

progress bar animation issue on cancel

The expected result: In the example above you see me long pressing 2 times and afterward canceling the long-press once. I would expect the red progress bar to scale down again and keep its position centered if the longPress was canceled. But as you can see, the progress bar changes its position.

What is causing this issue and how could it be solved while still using swiftUI and GestureState

Here is the code:


struct DiamondPress: View {
    
    @GestureState var isDetectingLongPress = false
    @State var completedLongPress = false
    
    var longPress: some Gesture {
        LongPressGesture(minimumDuration: 2)
        .updating($isDetectingLongPress) { currentState, gestureState, transaction in
            gestureState = currentState
            transaction.animation = Animation.linear(duration: 2.0)
        }
        .onEnded { _ in
            self.completedLongPress.toggle()
        }
    }

    var body: some View {
        
        ZStack {           
            Color.offWhite
            
            RoundedRectangle(cornerRadius: 12, style: .continuous)
            .frame(width: 100, height: 100, alignment: .center)
            .foregroundColor(.white)
            .scaleEffect(completedLongPress ? 2.0 : 1.0)
            .gesture(longPress)
            .animation(.easeIn(duration: 0.2))
                
            // here is the red progress bar:
            Rectangle()
            .frame(
               width: !isDetectingLongPress ? CGFloat(5) : CGFloat(100),
               height: 5, alignment: .center
            )
            .foregroundColor(.red)
        }
        .edgesIgnoringSafeArea(.all)
    }
}

Thanks a bunch, any help or hint is highly appreciated.

0

There are 0 best solutions below