Home > Software design >  SwiftUI basic animation
SwiftUI basic animation

Time:11-07

Let's say I have a number and I want to animate the transition each time it changes its value. So the value disappears to the left and the new increased value appears from the right. Can this easily be made using .transition(.slide)?

struct ContentView: View {
    @StateObject var viewModel = ViewModel()

    var body: some View {
        VStack(spacing: 64) {
            Text(viewModel.count.description)
                .font(.largeTitle)
            Button("Increment", action: viewModel.increment)
        }
    }
}

final class ViewModel: ObservableObject {
    @Published var count = 0

    func increment() {
        count  = 1
    }
}

CodePudding user response:

The .slide transition by default inserts from left and removes to right. We can use asymmetric move transition to achieve your goal.

Here is a raw demo of possible approach. Tested with Xcode 13 / iOS 15.

demo

struct ContentView: View {
    @StateObject var viewModel = ViewModel()

    var body: some View {
        VStack(spacing: 64) {
            // transition works on view insertion/remove that is
            // why we conditionally switch views
            if 1 == viewModel.count % 2 {
                NumberView(number: viewModel.count)
            } else {
                NumberView(number: viewModel.count)
            }
            Button("Increment", action: viewModel.increment)
        }
        .animation(.default, value: viewModel.count)
    }
}

// By default on transition view is removed to the edge from
// which it appears, that is why we need asymmetric transition
struct NumberView: View {
    let number: Int
    var body: some View {
        Text("\(number)")
            .font(.largeTitle)
            .frame(maxWidth: .infinity)
            .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
    }
}
  • Related