Skip to main content

How to animate the size of text

About 3 minSwiftSwiftUIArticle(s)bloghackingwithswift.comcrashcourseswiftswiftuixcodeappstore

How to animate the size of text 관련

SwiftUI by Example

Back to Home

How to animate the size of text | SwiftUI by Example

How to animate the size of text

Updated for Xcode 15

From iOS 16 and onwards, SwiftUI can animate text beautifully right out of the box – it takes no extra work from us. So, code like this smoothly animate some text between two different sizes, re-rendering the text automatically so it’s always crisp:

struct ContentView: View {
    @State private var fontSize = 32.0

    var body: some View {
        Text("Hello, World!")
            .font(.custom("Georgia", size: fontSize))
            .onTapGesture {
                withAnimation(.spring(response: 0.5, dampingFraction: 0.5, blendDuration: 1).repeatForever()) {
                    fontSize = 72
                }
            }
    }
}

Download this as an Xcode projectopen in new window

If you need to target iOS 15 and below then SwiftUI doesn’t have a built-in way to animate text size, but we can create an animatable view modifier that makes the effect possible. This is not the same as using a simple scaleEffect() modifier – that will cause your text to become blurry when scaled up, whereas this custom animation will re-render your text correctly so it looks great at all sizes.

This takes several steps:

1, Creating an animatable view modifier that accepts a name and size, and uses the size property for its animatable data. 2, Wrapping that in a View extension to make it easier to use. 3, Trying it out in a SwiftUI View.

Here’s a complete example in code:

// A modifier that animates a font through various sizes.
struct AnimatableCustomFontModifier: ViewModifier, Animatable {
    var name: String
    var size: Double

    var animatableData: Double {
        get { size }
        set { size = newValue }
    }

    func body(content: Content) -> some View {
        content
            .font(.custom(name, size: size))
    }
}

// To make that easier to use, I recommend wrapping
// it in a `View` extension, like this:
extension View {
    func animatableFont(name: String, size: Double) -> some View {
        self.modifier(AnimatableCustomFontModifier(name: name, size: size))
    }
}

// An example View trying it out
struct ContentView: View {
    @State private var fontSize = 32.0

    var body: some View {
        Text("Hello, World!")
            .animatableFont(name: "Georgia", size: fontSize)
            .onTapGesture {
                withAnimation(.spring(response: 0.5, dampingFraction: 0.5, blendDuration: 1).repeatForever()) {
                    fontSize = 72
                }
            }
    }
}

Download this as an Xcode projectopen in new window

That’s it! To try it out, make an @State property to store your font size, then pass that into animatableFont().

If you wanted to use Apple’s system fonts, the best way to do that is with a separate modifier. This way you can be sure your UI stays updated if the font ever changes.

Here’s how that looks:

struct AnimatableSystemFontModifier: ViewModifier, Animatable {
    var size: Double
    var weight: Font.Weight
    var design: Font.Design

    var animatableData: Double {
        get { size }
        set { size = newValue }
    }

    func body(content: Content) -> some View {
        content
            .font(.system(size: size, weight: weight, design: design))
    }
}

extension View {
    func animatableSystemFont(size: Double, weight: Font.Weight = .regular, design: Font.Design = .default) -> some View {
        self.modifier(AnimatableSystemFontModifier(size: size, weight: weight, design: design))
    }
}

struct ContentView: View {
    @State private var fontSize = 32.0

    var body: some View {
        Text("Hello, World!")
            .animatableSystemFont(size: fontSize)
            .onTapGesture {
                withAnimation(.spring(response: 0.5, dampingFraction: 0.5, blendDuration: 1).repeatForever()) {
                    fontSize = 72
                }
            }
    }
}

Download this as an Xcode projectopen in new window

I first saw this technique applied in Apple sample codeopen in new window.

Similar solutions…
How to animate changes in binding values | SwiftUI by Example

How to animate changes in binding values
How to animate SF Symbols | SwiftUI by Example

How to animate SF Symbols
How to make a fixed size Spacer | SwiftUI by Example

How to make a fixed size Spacer
How to automatically switch between HStack and VStack based on size class | SwiftUI by Example

How to automatically switch between HStack and VStack based on size class
How to create different layouts using size classes | SwiftUI by Example

How to create different layouts using size classes

이찬희 (MarkiiimarK)
Never Stop Learning.