设置导航栏标题字体

问题描述 投票:0回答:8

这是一个 SwiftUI 问题,而不是 UIKit

我正在尝试使用 SwiftUI 为导航栏标题设置不同的字体。我怀疑这还不受支持。这是我尝试过的:

var body: some View {
  NavigationView {
    .navigationBarTitle(Text("Dashboard").font(.subheadline), displayMode: .large)
  }
}

无论我对

.font
设置做什么,它都不会改变文本。我还尝试设置自定义字体并删除
displayMode
属性。

有人能够让它发挥作用吗?

fonts navigationbar swiftui
8个回答
58
投票

在 SwiftUI 中,此时我们无法直接更改

navigationBarTitle
字体,但您可以像这样更改导航栏外观,

struct YourView: View {
    init() {
        //Use this if NavigationBarTitle is with Large Font
        UINavigationBar.appearance().largeTitleTextAttributes = [.font : UIFont(name: "Georgia-Bold", size: 20)!]

        //Use this if NavigationBarTitle is with displayMode = .inline
        //UINavigationBar.appearance().titleTextAttributes = [.font : UIFont(name: "Georgia-Bold", size: 20)!]
    }
    var body: some View {
        NavigationView {
            Text("Hello World!")
              .navigationBarTitle(Text("Dashboard").font(.subheadline), displayMode: .large)
            //.navigationBarTitle (Text("Dashboard"), displayMode: .inline)
        }
    }
}

20
投票

在 iOS 14 SwiftUI 中,您可以使用工具栏修饰符自定义视图导航栏标题,将放置类型 .principal 的 ToolbarItem 设置为新的工具栏修饰符。

NavigationView {
    Text("any text")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .principal) {
                VStack {
                    Text("Nav Title")
                      .font(.system(size: 20))
                      .foregroundColor(Color.black)
                }
            }
        }
}

13
投票

如果您需要为 SF 系列使用新的圆角脸,您可以使用此片段

    let design = UIFontDescriptor.SystemDesign.rounded
    let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .largeTitle)
                                     .withDesign(design)!
    let font = UIFont.init(descriptor: descriptor, size: 48)
    UINavigationBar.appearance().largeTitleTextAttributes = [.font : font]

7
投票

我不太喜欢修改视图的 Inits 中的内容,但是,我不确定是否有更好的方法。相反,我将其移至 ViewModifier 以保持整洁:

struct SpecialNavBar: ViewModifier {

    init() {
        UINavigationBar.appearance().largeTitleTextAttributes = [.font: UIFont(name: "Georgia-Bold", size: 20)!]
    }

    func body(content: Content) -> some View {
        content
    }

}

extension View {

    func specialNavBar() -> some View {
        self.modifier(SpecialNavBar())
    }

}

然后使用:

struct MyView: View {

    var body: some View {
        NavigationView { 
            content
                .specialNavBar()
        }
    }

}

3
投票

您需要的所有设置都在 init() 内。和他们一起玩,了解什么负责什么。几个小时前,这段代码帮助我理解了导航栏设置。我不记得在哪里找到的。

struct ContentView: View {
    init() {
        // this is not the same as manipulating the proxy directly
        let appearance = UINavigationBarAppearance()
        
        // this overrides everything you have set up earlier.
        appearance.configureWithTransparentBackground()
        
        // this only applies to big titles
        appearance.largeTitleTextAttributes = [
            .font : UIFont.systemFont(ofSize: 20),
            NSAttributedString.Key.foregroundColor : UIColor.white
        ]
        // this only applies to small titles
        appearance.titleTextAttributes = [
            .font : UIFont.systemFont(ofSize: 20),
            NSAttributedString.Key.foregroundColor : UIColor.white
        ]
        
        //In the following two lines you make sure that you apply the style for good
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
        UINavigationBar.appearance().standardAppearance = appearance
        
        // This property is not present on the UINavigationBarAppearance
        // object for some reason and you have to leave it til the end
        UINavigationBar.appearance().tintColor = .white
        
    }
    var body: some View {
        NavigationView {
            ZStack {
                Color.black
                    .edgesIgnoringSafeArea([.all])
                NavigationLink(destination: ContentView2()) {
                    Text("push")
                }
            }
            .navigationBarTitle("", displayMode: .inline)
            .navigationBarBackButtonHidden(true)
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
struct ContentView2: View {
    
    var body: some View {
        
            ZStack {
                Color.black
                    .edgesIgnoringSafeArea([.all])
                NavigationLink(destination: ContentView()) {
                    Text("push")
                }
            }
            .navigationBarTitle("My Custom White title", displayMode: .inline)
        
    }
}

P。 S:代码取自here


0
投票

如果你想在修改时避免影响所有UINavigationBar的外观

UINavigationBar.appearance()
,请考虑以下代码:

import SwiftUI

struct NavigationStyleLayer: UIViewControllerRepresentable {
  @MainActor
  final class ViewController: UIViewController {
    override func viewDidLoad() {
      super.viewDidLoad()
      view.backgroundColor = .clear
      view.isUserInteractionEnabled = false
    }

    override func didMove(toParent parent: UIViewController?) {
      super.didMove(toParent: parent)

      if let navigationController = parent?.navigationController as? UINavigationController {
        navigationController.navigationBar.standardAppearance.largeTitleTextAttributes = [.font: UIFont.systemFont(ofSize: 17.0)]
      }
    }
  }

  func makeUIViewController(context: Context) -> ViewController {
    .init()
  }

  func updateUIViewController(_ uiViewController: ViewController, context: Context) {

  }
}

在您的 SwiftUI 视图代码中...

import SwiftUI

struct SwiftUIView: View {
  var body: some View {
    NavigationStack {
      Text("Hello, World!")
        .navigationTitle("Hello World!")
        .background {
          NavigationStyleLayer()
        }
    }
  }
}


0
投票

均可更改大标题和小标题。 如果有更多的默认 init 可能会更好,但这对我来说已经足够了。

init() {
        NavigationBarConfigurator.configureTitles()
            }
struct NavigationBarConfigurator {
    static func configureTitles() {
        let appearance = UINavigationBarAppearance()       
        let design = UIFontDescriptor.SystemDesign.rounded
        if let descriptorWithDesign = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .largeTitle)
                                                     .withDesign(design),
           let descriptorWithTraits = descriptorWithDesign.withSymbolicTraits(.traitBold) {
            let font = UIFont(descriptor: descriptorWithTraits, size: 34)
            appearance.largeTitleTextAttributes = [.font: font, .foregroundColor: UIColor.label]
        }
        if let smallTitleDescriptorWithDesign = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .headline)                                                              .withDesign(design) {
                    let smallTitleFont = UIFont(descriptor: smallTitleDescriptorWithDesign, size: 24)
            appearance.titleTextAttributes = [.font:smallTitleFont, .foregroundColor: UIColor.label]
                }
        UINavigationBar.appearance().standardAppearance = appearance
    }
}

0
投票

要获得较小的居中导航栏标题,就像您在 iPhone 设置的子屏幕中看到的那样,只需使用:

.navigationBarTitle(Text("Dashboard").font(.subheadline), displayMode: .inline)
© www.soinside.com 2019 - 2024. All rights reserved.