Created
August 24, 2022 23:40
-
-
Save SoundBlaster/1b6653432ad860459328c839b67d36ca to your computer and use it in GitHub Desktop.
Custom Dynamic Font for SwiftUI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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