Animating Text with Style in SwiftUI

Learn how to create a text animation in SwiftUI with this tutorial for UX/UI designers. Explore font scaling, alignment shifts, and smooth transitions

A UX/UI Designer’s Guide to Text Animation with SwiftUI inspired by some of the templates you can find at savee.it This tutorial walks through creating a dynamic text animation in SwiftUI, where the word “inspiration” shifts alignment and scales in a looping animation.

Final Result

  • The word “inspiration” repeats in a column.
  • The text grows and shrinks dynamically.
  • The alignment of the text smoothly transitions between leading and trailing.

Image from the Animating Text with Style in SwiftUI

Step 1: Set Up the SwiftUI View

Create a new SwiftUI View in Xcode.

  1. Open Xcode.
  2. Create a new SwiftUI View file.
  3. Name it TextAnimation001.swift.

Step 2: Define the Basic Structure

Start by structuring the view using GeometryReader and VStack.

Code:

import SwiftUI
struct TextAnimation001: View {
    var body: some View {
        GeometryReader { geometry in
            VStack {
                Spacer()
                ForEach(1..<9) { index in
                    Text("inspiration")
                        .frame(width: geometry.size.width - 32, alignment: .leading)
                        .kerning(-2)
                        .textCase(.uppercase)
                        .font(.system(size: 30, weight: .bold))
                        .padding(.horizontal, 16)
                }
                Spacer().frame(height: 64)
            }
        }
    }
}
#Preview {
    TextAnimation001()
}

What This Does:

  • Uses GeometryReader to adapt to different screen sizes.
  • Creates a VStack with multiple Text elements.
  • Adjusts font size and kerning to improve readability.
  • Preview It: Run the app in the Xcode preview window.

Step 3: Add Animation State

Next, introduce @State properties to animate the text.

Code Update:

@State private var isAnimating = false
@State private var isAnimating2 = false
@State private var alignment: Alignment = .leading

Why This Matters:

  • isAnimating controls text scaling.
  • isAnimating2 determines alignment shifts.
  • alignment dynamically changes from .leading to .trailing.

Step 4: Adjust Font Size Dynamically

Modify the text size to grow and shrink in animation.

Code:

func calculateFontSize(for index: Int) -> CGFloat {
    let baseSize: CGFloat = 10
    let sizeVariation: CGFloat = 60
    let normalizedIndex = CGFloat(index) / 9 // Normalize index between 0 and 1
    return baseSize + (isAnimating ? (1 - normalizedIndex) : normalizedIndex) * sizeVariation
}

Explanation:

  • The font size changes dynamically based on isAnimating.
  • The text grows from small to large, then reverses.

Step 5: Animate Alignment & Scaling

Now, define the startAnimationLoop() function to trigger the animations.

Code:

func startAnimationLoop() {
    Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) { _ in
        withAnimation(.easeInOut(duration: 1)) {
            isAnimating.toggle()
        }
    }
    Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { _ in
        withAnimation(.easeInOut(duration: 1)) {
            isAnimating2.toggle()
            alignment = isAnimating2 ? .trailing : .leading
        }
    }
}

How It Works:

  • The first timer runs every 1.5 seconds, toggling isAnimating (scaling effect).
  • The second timer runs every 3 seconds, switching alignment.

Step 6: Trigger Animation on Appear

Modify the body to start the animation loop.

Code:

.onAppear {
    startAnimationLoop()
}

Final SwiftUI Code

Here’s the full working SwiftUI animation:

import SwiftUI
struct TextAnimation001: View {
    @State private var isAnimating = false
    @State private var isAnimating2 = false
    @State private var alignment: Alignment = .leading
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                VStack {
                    Spacer()
                    ForEach(1..<9) { index in
                        Text("inspiration")
                            .frame(width: geometry.size.width - 32, alignment: alignment)
                            .kerning(-2)
                            .textCase(.uppercase)
                            .frame(height: calculateFontSize(for: index) / 1.3)
                            .font(.system(size: calculateFontSize(for: index), weight: .bold))
                            .padding(.horizontal, 16)
                    }
                    Spacer().frame(height: 64)
                }
                .onAppear {
                    startAnimationLoop()
                }
            }
        }
    }
    
    func startAnimationLoop() {
        Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) { _ in
            withAnimation(.easeInOut(duration: 1)) {
                isAnimating.toggle()
            }
        }
        
        Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { _ in
            withAnimation(.easeInOut(duration: 1)) {
                isAnimating2.toggle()
                alignment = isAnimating2 ? .trailing : .leading
            }
        }
    }
    
    func calculateFontSize(for index: Int) -> CGFloat {
        let baseSize: CGFloat = 10
        let sizeVariation: CGFloat = 60
        let normalizedIndex = CGFloat(index) / 9
        return baseSize + (isAnimating ? (1 - normalizedIndex) : normalizedIndex) * sizeVariation
    }
}
#Preview {
    TextAnimation001()
}

Step 7: Run and Test

  • Run the SwiftUI preview in Xcode
  • Observe the text growing, shrinking, and shifting
  • Adjust the timing and font scaling for desired effect

Final Result in Motion

Here’s a visual representation of how the animation works:

Image from the Animating Text with Style in SwiftUI article on Abduzeedo

Before Animation Starts

  • Text is aligned to the left
  • Font size is static

During Animation

  • Text alternates between left and right
  • Font sizes dynamically scale up and down

Conclusion

This SwiftUI animation is a simple yet effective way to explore text effects for UX/UI designers. Play around with timing, easing, and font variations to create unique animations!

Next Steps:

  1. Try different fonts and colors.
  2. Experiment with .scaleEffect() for additional effects.
  3. Add gesture-based triggers instead of timers.