Is there a way in SwiftUI to fulfill scrolling animations between 2 numbers

Viewed 83
1 Answers

This is a very rudimentary build of the same thing. I'm not sure if you're wanting to do it on a per-digit basis, however this should give you a solid foundation to work off of. The way that I'm handling it is by using a geometry reader. You should be able to easily implement this view by utilizing an HStack for extra digits/decimals. The next thing I would do would be to create an extension that handles returning the views based on the string representation of your numeric value. Then that string is passed as an array and views created for each index in the array, returning a digit flipping view. You'd then have properties that are having their state observed, and change as needed. You can also attach an .opacity(...) modifier to give it that faded in/out look, then multiply the opacity * n where n is the animation duration.

In this example you can simply tie your Digit value to the previewedNumber and it should take over from there.

struct TestView: View {
    
    @State var previewedNumber = 0;
    
    var body: some View {
        ZStack(alignment:.bottomTrailing) {
            
            GeometryReader { reader in
                VStack {
                    ForEach((0...9).reversed(), id: \.self) { i in
                        Text("\(i)")
                            .font(.system(size: 100))
                            .fontWeight(.bold)
                            .frame(width: reader.size.width, height: reader.size.height)
                            .foregroundColor(Color.white)
                            .offset(y: reader.size.height * CGFloat(previewedNumber))
                            .animation(.linear(duration: 0.2))
                    }
                }.frame(width: reader.size.width, height: reader.size.height, alignment: .bottom)
            }
            .background(Color.black)
            
            Button(action: {
                withAnimation {
                    previewedNumber += 1
                    if (previewedNumber > 9) {
                        previewedNumber = 0
                    }
                }
            }, label: {
                Text("Go To Next")
            }).padding()
        }
    }
}
Related