by abduzeedo
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.
Step 1: Set Up the SwiftUI View
Create a new SwiftUI View in Xcode.
- Open Xcode.
- Create a new SwiftUI View file.
- 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:
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:
- Try different fonts and colors.
- Experiment with .scaleEffect() for additional effects.
- Add gesture-based triggers instead of timers.