Skip to content
Count Up preview
An animated render of the SwiftUI source on this page.

Count Up

From syxUI — written for both platforms, not translated between them.

A figure that counts up to its value and re-animates when it changes.

Text Effects · SwiftUI · Flutter · iOS 17 · Flutter 3.16

  • text
  • number
  • counter
  • count up
  • stats
  • animation

The actual source

CountUp.swift
// Count Up · syxUI · https://syxui.dev/components/count-up
// Free in any project. Keep this line and credit syxUI where a person can read it.

import SwiftUI

/// A number that counts up to its value and re-animates whenever it changes.
///
/// Digits are monospaced so the figure does not jitter as it climbs — the one
/// detail that separates a polished counter from a twitchy one.
struct CountUp: View {
    var value: Double = 24183.5
    var format: FloatingPointFormatStyle<Double> = .number.precision(.fractionLength(0))
    var prefix: String = "$"
    var suffix: String = ""
    var duration: Double = 1.1
    var font: Font = .system(size: 44, weight: .bold, design: .rounded)
    /// Drive the count yourself with 0...1 instead of running it on appear.
    var progress: Double? = nil

    @Environment(\.accessibilityReduceMotion) private var reduceMotion
    @State private var displayed: Double = 0

    var body: some View {
        Text(prefix + (progress.map { value * $0 } ?? displayed).formatted(format) + suffix)
            .font(font)
            .monospacedDigit()
            .contentTransition(.numericText(value: displayed))
            .onAppear { run() }
            .onChange(of: value) { _, _ in run() }
            .accessibilityLabel(prefix + value.formatted(format) + suffix)
    }

    private func run() {
        guard progress == nil else { return }
        guard !reduceMotion else { displayed = value; return }
        displayed = 0
        withAnimation(.easeOut(duration: duration)) { displayed = value }
    }
}

#Preview {
    CountUp()
        .padding(30)
}
iOS 17 · No dependencies

SwiftUI note. contentTransition(.numericText) rolls the digits rather than cross-fading the whole string. Requires iOS 17.

Dependencies

SwiftUI
No external dependencies

Requires iOS 17

Flutter
No external dependencies

Requires Flutter 3.16