radicalappdev
radicalappdev

Reputation: 1422

Set System to always use Rounded Font?

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

Answers (5)

Imanou Petit
Imanou Petit

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

Kirsteins
Kirsteins

Reputation: 27345

Starting from iOS 16.1 you can use .fontDesign(.rounded)

https://developer.apple.com/documentation/swiftui/view/fontdesign(_:)

Upvotes: 2

Asperi
Asperi

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

Rohit Makwana
Rohit Makwana

Reputation: 4905

You could create an extension on Font like below

  1. Parameter Font size & weight
  2. 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

Andrew
Andrew

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

Related Questions