Skip to content

Instantly share code, notes, and snippets.

@simonliotier
Last active December 11, 2019 14:27
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonliotier/d533b7a2636a8bd2263592d520f9067a to your computer and use it in GitHub Desktop.
Save simonliotier/d533b7a2636a8bd2263592d520f9067a to your computer and use it in GitHub Desktop.
Example of how to get Dynamic Type with custom fonts in SwiftUI
import SwiftUI
/// Example of how to get Dynamic Type with custom fonts in SwiftUI.
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Text("A large title").customFont(.largeTitle) // "Optima-ExtraBlack", 28
Text("A body").customFont(.body) // "Kailasa", 16
Text("A caption").customFont(.caption2) // "IowanOldStyle-Italic", 11
}
}
}
extension View {
func customFont(_ textStyle: UIFont.TextStyle) -> Self.Modified<CustomFont> {
return modifier(CustomFont(textStyle: textStyle))
}
}
struct CustomFont: ViewModifier {
let textStyle: UIFont.TextStyle
/// Will trigger the refresh of the view when the ContentSizeCategory changes.
@Environment(\.sizeCategory) var sizeCategory: ContentSizeCategory
func body(content: Content) -> some View {
guard let fontDescription = fontDescriptions[textStyle] else {
fatalError()
}
let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
let fontSize = fontMetrics.scaledValue(for: fontDescription.1)
return content.font(.custom(fontDescription.0, size: fontSize))
}
}
/// Define the custom fonts to use, depending on the TextStyle.
typealias CustomFontDescription = (String, CGFloat)
private var fontDescriptions: [UIFont.TextStyle: CustomFontDescription] = [
.largeTitle: ("Optima-ExtraBlack", 28),
.body: ("Kailasa", 16),
.caption2: ("IowanOldStyle-Italic", 11)
// ... other styles
]
@Drarok
Copy link

Drarok commented Aug 29, 2019

This doesn't seem to work for me – the following code displays both views at the same size:

            FontExampleView()
            FontExampleView().environment(\.sizeCategory, .accessibilityExtraExtraExtraLarge)

@mortenbekditlevsen
Copy link

My take is that UIFontMetrics scaledValue responds to current dynamic type setting, but not the SwiftUI sizeCategory environment.
So this ought to work in a real app although it would be even better with a solution that worked with 'pure' SwiftUI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment