Skip to content

Instantly share code, notes, and snippets.

@SoundBlaster
Created August 24, 2022 23:40
Show Gist options
  • Save SoundBlaster/1b6653432ad860459328c839b67d36ca to your computer and use it in GitHub Desktop.
Save SoundBlaster/1b6653432ad860459328c839b67d36ca to your computer and use it in GitHub Desktop.
Custom Dynamic Font for SwiftUI
//
// CustomFont.swift
// BLNC
//
// Created by Egor Merkushev on 31.05.2021.
// Copyright © 2021 Egor Merkushev. All rights reserved.
// Source: https://stackoverflow.com/a/58971579/602249
import SwiftUI
extension View {
func customFont(_ textStyle: UIFont.TextStyle) -> ModifiedContent<Self, 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 {
return content.font(.system(.body));
}
let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
let fontSize = fontMetrics.scaledValue(for: fontDescription.0)
return content.font(.system(size: fontSize, weight: fontDescription.1, design: .rounded))
}
}
/// Define the custom fonts to use, depending on the TextStyle.
typealias CustomFontDescription = (CGFloat, Font.Weight)
private var fontDescriptions: [UIFont.TextStyle: CustomFontDescription] = [
.headline: (17, .semibold),
.subheadline: (15, .regular),
.largeTitle: (34.0, .regular),
.title1: (28, .regular),
.title2: (22.0, .regular),
.title3: (20.0, .regular),
.callout: (16.0, .regular),
.body: (17.0, .regular),
.footnote: (13.0, .regular),
.caption1: (12.0, .regular),
.caption2: (11.0, .regular)
]
@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
struct ScaledFont: ViewModifier {
@Environment(\.sizeCategory) var sizeCategory
var name: String
var size: CGFloat
func body(content: Content) -> some View {
let scaledSize = UIFontMetrics.default.scaledValue(for: size)
return content.font(.custom(name, size: scaledSize))
}
}
@available(iOS 13, macCatalyst 13, tvOS 13, watchOS 6, *)
extension View {
func scaledFont(name: String, size: CGFloat) -> some View {
return self.modifier(ScaledFont(name: name, size: size))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment