Reputation: 17725
I would like to know how to use a system font in my SwiftUI
app with a custom size that supports dynamic size (that changes when the user changes the text size on the device, font size changes dynamically).
I can use the standard .body
, .title
etc for system fonts, however I want to use a custom size which is slightly different however still want to make sure it works with dynamic types
//Font size doesn't change when the user changes his preferred text size on the device
Text("hello")
.font(.system(size: 14, weight: .bold, design: .default))
I am targeting iOS 15
, I am looking for something on the lines of the following for system font:
static func custom(_ name: String, size: CGFloat, relativeTo textStyle: Font.TextStyle) -> Font
Upvotes: 1
Views: 793
Reputation: 17725
Following Font function helps achieve custom font size relative to TextStyle:
static func custom(
_ name: String,
size: CGFloat,
relativeTo textStyle: Font.TextStyle
) -> Font
Upvotes: 1
Reputation: 6081
I made it with somewhat hacky font size estimation based on current sizeCategory
:
public enum AppTextStyle {
case veryCustomTextStyle
case anotherCustomTextStyle
}
struct ScaledFontModifier: ViewModifier {
@Environment(\.sizeCategory) var sizeCategory
var textStyle: AppTextStyle
func body(content: Content) -> some View {
content.font(font(for: textStyle))
}
private func font(for style: AppTextStyle) -> Font {
switch style {
case .veryCustomTextStyle:
return .system(size: scaledValue(for: 42))
case .anotherCustomTextStyle:
return .system(size: scaledValue(for: 42), weight: .medium)
}
}
private func scaledValue(for size: CGFloat) -> CGFloat {
switch sizeCategory {
case .extraSmall:
return size - 3
case .small:
return size - 2
case .medium:
return size - 1
case .large:
return size
case .extraLarge:
return size + 2
case .extraExtraLarge:
return size + 4
case .extraExtraExtraLarge:
return size + 6
case .accessibilityMedium:
return size + 11
case .accessibilityLarge:
return size + 16
case .accessibilityExtraLarge:
return size + 23
case .accessibilityExtraExtraLarge:
return size + 30
case .accessibilityExtraExtraExtraLarge:
return size + 36
@unknown default:
return size
}
}
}
public extension View {
func font(_ textStyle: AppTextStyle) -> some View {
modifier(ScaledFontModifier(textStyle: textStyle))
}
}
You can use it along the built-in fonts, or you can put all your app text styles in AppTextStyle
enum:
Text("Hello")
.font(.body)
Text("World")
.font(.veryCustomTextStyle)
Upvotes: 0