简体   繁体   中英

Offset doesn't reset after onTapGesture - SwiftUI

Im trying to create a card that slides when it is tapped on and then goes back to original position without tapping again the.onEnded() function of tap gesture isn't working

This is the test code

struct ContentView: View {

@State var tapped = false
var body: some View {
    VStack {
        ZStack {
            Rectangle()
                .fill(Color.green)
                .frame(height: 300)
            
            Rectangle()
                .fill(Color.red)
                .frame(width: 290, height: 64)
                .offset(y: tapped ? 118 : 0)
                .onTapGesture {
                    self.tapped.toggle()
            }
            .animation(.easeInOut)
        }
        
        Spacer()
    }.edgesIgnoringSafeArea(.all)
}

}

Applied properties does not reset magically by themselves - you need to change them as/when needed.

Here is simplest possible solution. Tested with Xcode 11.4 / iOS 13.4

演示

var body: some View {
    VStack {
        ZStack {
            Rectangle()
                .fill(Color.green)
                .frame(height: 300)

            Rectangle()
                .fill(Color.red)
                .frame(width: 290, height: 64)
                .offset(y: tapped ? 118 : 0)
                .onTapGesture {
                    self.tapped.toggle()
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                        self.tapped.toggle()
                    }
            }
            .animation(Animation.easeInOut(duration: 0.5))
        }

        Spacer()
    }.edgesIgnoringSafeArea(.all)
}

backup

Solved it using a delay in explicit animation. A repeat-while cycle allows you to specify how many times the rectangle will be bounced:

struct ContentView: View {

@State var tapped = false
    @State var countOfBounce: Double = 0
    @State var addDelay: Double = 0

var body: some View {
    VStack {
        ZStack {
            Rectangle()
                .fill(Color.green)
                .frame(height: 300)

            Rectangle()
                .fill(Color.red)
                .frame(width: 290, height: 64)
                .offset(y: tapped ? 118 : 0)
                .onTapGesture {
                    repeat {
                    withAnimation(.linear(duration: 0.5).delay(0 + addDelay)){
                    self.tapped.toggle()
                    }
                    countOfBounce += 1
                    addDelay += 0.5
                } while countOfBounce < 2
                    countOfBounce = 0
                    addDelay = 0
            }
        }
        Spacer()
        }.edgesIgnoringSafeArea(.all)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM