.contentTransition(.numericText()) not working as expectation

In this tutorial, I will show you why .contentTransition(.numericText()) does not work as per our expectations. If you have tried using .contentTransition(.numericText()) in your SwiftUI project, it may happen that it will not work. That means it will not be showing any animation at all.

Why .contentTransition(.numericText()) does not work in SwiftUI

You might see several tutorials on this and find that on clicking on a button, the animation of .contentTransition(.numericText()) is working fine.

But when you try to use the same on the text/numeric value that is changing dynamically through your program, it will not show any animation.

The reason has been clearly mentioned in SwiftUI’s official documentation.

The contentTransition will only work if the value is inside an animation block.

If the dynamic value-changing logic/program is not inside withAnimation block, then .contentTransition(.numericText()) will not take any effect.

So you must have to put that inside that block like this:

withAnimation {
//Your dynamic value should be here so
}

How to implement .contentTransition(.numericText())

Let’s take an example to show that you can understand it in a better way.

Here I am taking an example from our previous article: Make a countdown timer in SwiftUI

If you check that tutorial, there is no animation effect. But now I will be adding animation effect to that using .contentTransition(.numericText())

import SwiftUI

struct ContentView:View{
   
    @State var timeRemaining: Int = 5

    @State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        
        VStack(spacing: 30){
                Text("Time remaining: \(timeRemaining)")
                    .contentTransition(.numericText())
                    .onReceive(timer){_ in
                        
                        if timeRemaining>0{
        
                            timeRemaining -= 1
                        }
                        else
                        {
                            timeRemaining = 50
                        }
                    }
        }
  }
}

As you can see on line number 13, I have used .contentTransition(.numericText()).

And the output is like this:

.contentTransition(.numericText()) not working

As you can see, there is no animation effect and .contentTransition(.numericText()) is not working.

How to fix that?

import SwiftUI

struct ContentView:View{
   
    @State var timeRemaining: Int = 5

    @State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        
        VStack(spacing: 30){
                Text("Time remaining: \(timeRemaining)")
                    .contentTransition(.numericText())
                    .onReceive(timer){_ in
                        
                        if timeRemaining>0{
                            withAnimation{ timeRemaining -= 1
                            }
                        }
                        else
                        {
                            timeRemaining = 50
                        }
                    }
        }
  }
}

Take a look at line no 17. I have wrapped that using withAnimation block.

withAnimation{ timeRemaining -= 1
}

Now the output will be like this:

.contentTransition(.numericText()) SwiftUI

Leave a Reply

Your email address will not be published. Required fields are marked *