Reputation: 1422
In SwiftUI, is there a way to make the rounded version of the system font the default for all styles? I'm using one of the system styles (.body, .title, .headline, etc) for all text in the app.
For example, I can use this on a single Text view
Text("some text")
.font(.system(.body, design: .rounded))
I'd like to avoid having to update every text view and field in my app like this. Is there some way to tell the environment to use the rounded design by default?
Upvotes: 7
Views: 2127
Reputation: 92549
Starting with iOS 16.1+ and macOS 13.0+, you can use the fontDesign(_:)
modifier to customize the font design within a SwiftUI view hierarchy.
Here's an example demonstrating how to apply a rounded font design across the entire app:
import SwiftUI
@main
struct MyDemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.fontDesign(.rounded)
}
}
}
However, this modifier does not affect the fonts used for navigation toolbar titles. To customize those, you need to configure their fonts using UINavigationBar.appearance()
. A suitable location to set this configuration is in the AppDelegate
class.
AppDelegate.swift:
import UIKit
final class AppDelegate: NSObject, UIApplicationDelegate, ObservableObject {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
let largeTitleFont = UIFont.preferredFont(forTextStyle: .largeTitle)
let newLargeFontDescriptor = largeTitleFont.fontDescriptor.withDesign(.rounded)?
.withSymbolicTraits(.traitBold) ?? largeTitleFont.fontDescriptor
let newLargeTitleFont = UIFont(descriptor: newLargeFontDescriptor, size: largeTitleFont.pointSize)
UINavigationBar.appearance().largeTitleTextAttributes = [.font: newLargeTitleFont]
let regularTitleFont = UIFont.preferredFont(forTextStyle: .headline)
let newRegularFontDescriptor = regularTitleFont.fontDescriptor.withDesign(.rounded)?
.withSymbolicTraits(.traitBold) ?? regularTitleFont.fontDescriptor
let newRegularTitleFont = UIFont(descriptor: newRegularFontDescriptor, size: regularTitleFont.pointSize)
UINavigationBar.appearance().titleTextAttributes = [.font: newRegularTitleFont]
return true
}
}
MyDemoApp.swift:
import SwiftUI
@main
struct MyDemoApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
.fontDesign(.rounded)
}
}
}
Upvotes: 1
Reputation: 27345
Starting from iOS 16.1 you can use .fontDesign(.rounded)
https://developer.apple.com/documentation/swiftui/view/fontdesign(_:)
Upvotes: 2
Reputation: 258117
Here is how it is possible to set environment font in root view, all subviews will have it by default.
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: Text("Details")) {
Text("Link")
}
Text("Tap on image to find details")
}
}.environment(\.font, Font.system(.body, design: .rounded))
}
Upvotes: 7
Reputation: 4905
You could create an extension on Font
like below
size
& weight
Parameter Font TextStyle
extension Font {
static func roundedFont(WithSize size: CGFloat, AndWeight weight:Weight) -> Font {
return Font.system(size: size, weight: weight, design: .rounded)
}
static func roundedFont(_ style: Font.TextStyle) -> Font {
return Font.system(style, design: .rounded)
}
}
You can call like:
- Text("Hello").font(Font.roundedFont(WithSize: 15.0, AndWeight: .bold))
- Text("Hello").font(Font.roundedFont(.body))
Upvotes: -1
Reputation: 28539
You could create an extension on Font
that has a function that automatically sets the design to being rounded, while still allowing you to set the TextStyle
extension Font {
static func roundedFont(_ style: Font.TextStyle) -> Font {
Font.system(style, design: .rounded)
}
}
Then you would use it like this:
struct ContentView: View {
var body: some View {
Text("Hello").font(.roundedFont(.body))
}
}
Upvotes: 3