numericText transition for normal SwiftUI View

Description

In Live Activities, we saw many beautiful animations that powered by .numericText() like Text(time, style: .timer), or even Text with .contentTransition(.numericText()) applied.

But it seems like in normal SwiftUI View, these beautiful animations are gone. Instead, we saw a blinking result or fade-in-out result.

Is that exactly right?

ScreenShots

In Live Activity:

In normal SwiftUI View:

Accepted Reply

Finally fixed in Xcode beta 6. Good work.

Replies

Finally fixed in Xcode beta 6. Good work.

I tried it on Xcode Version 15.0 beta 8 (15A5229m) but it does not seem to be working. My text is not animated in the app (not a widget). Do you have any idea why?

  • Sorry, I forgot to reply you. The answer below is correct, which you need to update your view within an animation block. But in your case, just add a transaction and set transaction.animation. Maybe it’ll work.

  • Thanks! It worked! See my reply below with the sample code.

Add a Comment

@alpennec

Had the same problem, but solved it by wrapping the trigger with an animation block. Try adding this below the Text view.

        .onTapGesture {
            
            withAnimation(.linear(duration: 0.3)) {
                self.number = Float.random(in: 0...1000)
            }
            
        }

Also, question for you: What app / theme are you using for that awesome code snippet?

The content transition '.numericText(countsDown:)' that was introduced in iOS 16 does not work on iOS 16... is that a bug? Has anyone reported it? It does not matter if I wrap the value update inside a withAnimation block or not, it does not work. On iOS 17 it does, but I want backward compatibility.

  • Exactly. It has been fixed in iOS 17. Sadly, if you really want to use it, you need to write a custom one.

Add a Comment

Here is a solution that works in iOS 17:

import SwiftUI

struct TimerTransitionView: View {
    var body: some View {
        Text(Date(timeIntervalSince1970: 1696563619), style: .timer)
            .contentTransition(.numericText())
            .transaction { t in
                t.animation = .default
            }
    }
}

#Preview {
    TimerTransitionView()
}

Thanks LiYanan04818 for the suggestion!

Add a Comment

Can be even better if you add the .monospacedDigit() modifier to the Text