João Gabriel
João GabrielJune 12, 2022

Hands-on: Typography in SwiftUI

Learn about some of the new typography features in SwiftUI, including support for animating text.
Hands-on: Typography in SwiftUI

At WWDC22, a bunch of new SwiftUI features were introduced. A few of them include some great updates to Text Views and typography.


First of all, now all the modifiers that could previously be applied exclusively to a Text view can now be applied to any View. So .bold(), for example, can now be used like so:

ContentView.swift
import SwiftUI
 
struct ContentView: View {
	var body: some View {
		VStack {
			Text("WWDC sessions yet to be watched:")
			Text("26")
		}.bold()
	}
}

Also, now all text properties are animatable natively. Let's take a look at some of them:

Size

Size animation made in SwiftUI
ContentView.swift
import SwiftUI
 
struct ContentView: View {
	@State var big = false
 
	var body: some View {
		Text("Size")
			.font(.system(size: big ? 20 : 14))
			.animation(.default, value: big)
			.onTapGesture {
				big.toggle()
			}
	}
}

Text size in SwiftUI could already be animated via a custom, animatable modifier or by the application of a scale effect. One of the benefits of this new solution is that it works better with word wrapping. What's also great is that it is now built into every Text view.

Weight

Weight animation made in SwiftUI

Smooth.

The weight of the system font in SwiftUI could already be animated via a custom modifier. This one has, too, the clear advantages mentioned above, including making it much easier to create nice text effects for your SwiftUI experiences.

ContentView.swift
import SwiftUI
 
struct ContentView: View {
	@State var heavy = false
 
	var body: some View {
		Text("Weight")
			.font(.system(size: 14, weight: heavy ? .heavy : .thin))
			.animation(.default, value: heavy)
			.onTapGesture {
				heavy.toggle()
			}
	}
}

Width

Width animation made in SwiftUI

San Francisco, the font family used in Apple's systems, now supports multiple widths: condensed, compressed and expanded are available to use – and they will smoothly transition from one to another. Using them in SwiftUI can be done by manually naming the font names, like so:

ContentView.swift
import SwiftUI
 
struct ContentView: View {
	@State var expanded = false
 
	var body: some View {
		Text("Width")
			.font(expanded ? .custom("SF Pro Expanded", size: 14) : .custom("SF Pro Compressed", size: 14))
			.animation(.default, value: expanded)
			.onTapGesture {
				expanded.toggle()
			}
	}
}

Before using these though, make sure that the new fonts are installed in the system or included in the app's bundle.


You can find more details on the new features of San Francisco in this WWDC22 session.


Compatible implementation

If you want to use text animation in older versions of the SDK, just implement the following modifier:

View+AnimatableFont.swift
import SwiftUI
 
/// Implements an animatable system font
struct AnimatableFontModifier: AnimatableModifier {
    var size: CGFloat
    var weight: Font.Weight = .black
 
    var animatableData: CGFloat {
        get { size }
        set { size = newValue }
    }
 
    func body(content: Content) -> some View {
        content
            .font(.system(size: size, weight: weight))
    }
}
 
extension View {
		/// Sets an animatable system font
    func animatableFont(size: CGFloat, weight: Font.Weight = .black) -> some View {
        self.modifier(AnimatableFontModifier(size: size, weight: weight))
    }
}

Thank you for reading through here! This was a great WWDC to be a part of. Stay tuned, and see you the next time.