Bruce Webster
Bruce Webster

Reputation: 541

Use dynamic text size .largeTitle but always 18% larger than normal in SwiftUI

I want to use dynamic text sizes in the system font. But our design wants the default large title to be a bit bigger than the 34pt Apple default.

How do I make my SwiftUI style .font(.largeTitle) relatively larger, i.e. 40pt at system default text size, but still scale proportionately when the user changes the system text size? Always 18% bigger than a normal .largeTitle.

I don't want to specify the San Francisco font name using .custom(<name>, size: <Float>, relativeTo: <Font.TextStyle>) as this generates a warning and misses out on getting the best optical variant.

I can use UIFont functions to adjust font metrics but I cannot convert the too-small SwiftUI Font to UIFont.

Upvotes: 2

Views: 3318

Answers (2)

Joseph
Joseph

Reputation: 863

See this answer here by Ashley Mills.

In case it gets removed I'll repeat it here:

extension Font {
    static let fortypt = Font.custom("", size: 40, relativeTo: .title)
}

To change the font, add the name (eg. for rounded system font, this works on iOS 15, I think you can just do .fontDesign(.rounded) on iOS 16.1+):

extension Font {
    static let fortypt = Font.custom(".AppleSystemUIFontRounded-Regular", size: 40, relativeTo: .title)
}

Then you can use the type like any other:

Text("Dynamic 40pt text")
    .font(.fortypt)

Upvotes: 1

Bruce Webster
Bruce Webster

Reputation: 541

I added this extension to UIFont to get the dynamic font size for a given TextStyle…

public extension UIFont {
    static func textStyleSize(_ style: UIFont.TextStyle) -> CGFloat {
        UIFont.preferredFont(forTextStyle: style).pointSize
    }
}

Then my SwiftUI ViewModifier can use and scale that. e.g:

.font(.system(size: UIFont.textStyleSize(.largeTitle) * 1.176, weight: .bold))

This gets the correct optical variant (such as the Display version for large, or more readable variant for small sizes) for the exact size I want as well as scaling relatively with the user's selected text size. Picking the text style closest to the desired size to base my size on helps to get the best proportions.

This seems the best available approach to me.

Upvotes: 2

Related Questions