Animating numeric text in SwiftUI with the Content Transition modifier

Animating numeric text in SwiftUI with the Content Transition modifier

Learn how to use the content transition modifier to animate numeric text in SwiftUI.

Content Transition is a simple modifier you can use to create animated transitions upon content change in your SwiftUI applications. For example, when you have a numeric value that changes over time or upon an action triggering the change, like the time on a timer or a currency that updates live.

In the following example, we will increment a value formatted as currency every time the button is pressed. The user interface is working fine at the moment, but when you tap the button, the value presented on our Text element doesn’t have any animation associated with it, so there is no feedback on the result of the action.

struct IncrementingCurrencyView: View {
    
    @State var value: Double = 0
    
    // 1. Formatter for our value to show as currency
    var currencyFormater: NumberFormatter = {
        var formatter = NumberFormatter()
        
        formatter.numberStyle = .currency
        formatter.currencySymbol = "$"
        
        return formatter
    }()
    
    var body: some View {
        VStack {
            // 2. Value being shown on the interface
            Text("\\(currencyFormater.string(from: value as NSNumber)!)")
                .font(.largeTitle)
                .bold()
            
            // 3. Button that increments the value
            Button {
                self.incrementValue(with: 11.99)
            } label: {
                Text("More money")
            }
        }
    }
    
    // 4. Function to increment the value
    func incrementValue(with amount: Double) {
        self.value += amount
    }
}

If you wrap the value changes inside a withAnimation(_:_:) block the text will animate with the default fade-in/fade-out animation.

func incrementValue(with amount: Double) {
    withAnimation {
        self.value += amount
    }
}
Example of the text change animated with a fade-in/fade-out animation.

We can use the modifier contentTransition(_:) to animate the transition of the content with an animation aligned with the change of numeric values. Let’s apply this modifier to the Text element of our interface presenting the numeric value to the user.

Text("\(currencyFormater.string(from: value as NSNumber)!)")
    .contentTransition(.numericText(value: value))
    .font(.largeTitle)
    .bold()
Animated content transition of the numeric values in the Text element

By adding the modifier and specifying that the type of transition is .numericText(value:) the proper animation will be used. There are other types of content transition and you can also define your own. Check out the official documentation for more:

ContentTransition | Apple Developer Documentation
A kind of transition that applies to the content within a single view, rather than to the insertion or removal of a view.