【问题标题】:How change .navigationBarTitle font in SwiftUI?如何在 SwiftUI 中更改 .navigationBarTitle 字体?
【发布时间】:2019-11-04 20:21:17
【问题描述】:

我正在使用带有 Xcode 11 的 SwiftUI,我想用这些代码行更改 NavigationBarTitle 字体:

.navigationBarTitle (Text("Navigation Bar Title"), displayMode: .inline)
    .font(.subheadline)

但什么也没发生。有什么建议或意见吗?

【问题讨论】:

标签: ios swift swiftui xcode11


【解决方案1】:

就我而言,上述答案不起作用。 但是下面的代码运行良好。

let appearance = UINavigationBarAppearance()
        
appearance.titleTextAttributes = [.font : UIFont(name: "Georgia-Bold", size: 20)!]

【讨论】:

    【解决方案2】:

    在 SwiftUI 5 中 UINavigationBar.appearance().titleTextAttributes 不起作用。您需要使用以下方法之一来更改标题中的字体:

            init () {
                UINavigationBar.appearance().largeTitleTextAttributes = [.font : UIFont(name: "Georgia", size: 20)!]
                // OR
                UINavigationBar.appearance().largeTitleTextAttributes = [.font:UIFont.preferredFont(forTextStyle:.text-style)]
            }
    

    .text-style 可以在 UIFont.TextStyle 文档中找到,例如

    .caption
    .body
    .title1
    .title2
    .title3
    etc
    

    更新 1(回答有关 cmets 中确切代码的问题)

    struct ContentView: View {
    
        init () {
            let paragraph = NSMutableParagraphStyle()
            paragraph.alignment = .center
            
            UINavigationBar.appearance().largeTitleTextAttributes = [.font:UIFont.preferredFont(forTextStyle:.title2),
                                                                     .foregroundColor:UIColor.systemBlue,
                                                                     .paragraphStyle: paragraph
                                                                    ]
    

    ...

    然后在体内我有这个。您可能应该注意 displayMode 参数

    // Body is in the same ContentView struct. Settings from init will be used in navigationBarTitle
    // listView() is just a custom function returning a SwiftUI's List()
    
    var body: some View {
    
    
            NavigationView {
                
            listView()
                .navigationBarTitle(
                    Text(self.accts.selCount <= 0 ? "Accounts" : "\(self.accts.selCount) selected")
                    ,
                    displayMode:.large)
    

    【讨论】:

    • 我没有看到这项工作。在父 NavigationView 的初始化和子视图中进行了尝试。你能分享一个关于这个 init 的确切位置的简短示例吗?
    • 谢谢,但我不确定我是否遵循。最后一个块有一个带有三个 AnyView 的 ViewBuilder 主体和一个带有内部导航视图的 TabView。目前尚不清楚 init 将放置在哪里......在由 func listView 或其他东西生成的视图中。你能写成一个可构建的 View 结构吗?我确实看到全局覆盖方法有效:stackoverflow.com/a/67172529/14433738
    • @Ryan 这很标准。 'init' 是一些“struct ContentView: View...”的构造函数。 ContentView 在 SceneDelegate.scene 函数中用于设置初始视图。 'var body' 在同一个 ContentView 结构中定义了内容的 UI。不确定是什么令人困惑。 init 和 'var body' 都定义在同一个 ContentView 类中。在body中你只需要注意一件事:navigationBarTitle
    • 稍微更新了答案,以明确“init”和“var body”都在同一个 ContentView 结构中,这是所有视图的根。
    • 该评论有助于阐明意图。仅供参考,来自使用 SwiftUI 制作了一些材料应用程序的读者,代码格式/语法有各种奇怪的三元组和括号和括号可能混合或没有复制,这使得对正在发生的事情产生了一些猜测。也许它对粘贴做一些事情。不过,感谢您提出的解决方案路线并花时间对此进行编辑。
    【解决方案3】:

    我认为你必须创建一个 NavigationBarBuilder。

    struct NavigationBarBuilder: UIViewControllerRepresentable {
    
        var build: (UINavigationController) -> Void = { _ in }
    
        func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationBarBuilder>) -> UIViewController {
    
            UIViewController()
        }
    
        func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationBarBuilder>) {
    
            if let navigationController = uiViewController.navigationController{
                self.build(navigationController)
            }
        }
    }
    

    您可以在内容视图中使用它。

    struct ContentView: View {
        var body: some View {
            NavigationView {
                Text("")
                    .navigationBarTitle("Türkiye", displayMode: .inline)
                    .background(NavigationBarBuilder {navigationController in
                        navigationController.navigationBar.barTintColor = .red
                        navigationController.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
                    })
            }
            .navigationViewStyle(StackNavigationViewStyle())
        }
    }
    

    祝你好运……

    【讨论】:

      【解决方案4】:

      在 SwiftUI 中,此时我们不能直接更改 navigationBarTitle 字体,但可以像这样更改 navigationBar 外观,

      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("TEST")
                  .navigationBarTitle (Text("TEST"), displayMode: .inline)
              }
          }
      }
      

      希望对你有所帮助。谢谢!!

      【讨论】:

        【解决方案5】:

        您不能使用.font 修饰符改变navigationBarTitle 的字体(在 Xcode 11-Beta2 中测试)。

        但是您可以构建自己的自定义 navigationBarView,并可以完全访问其任何子视图,如下所示:

        struct NavigationBarView: View {
        
            var body: some View {
        
                VStack(spacing: 0) {
                    Rectangle()
                        .foregroundColor(Style.Color.navigationBarColor)
                        .edgesIgnoringSafeArea(.top)
                        .frame(height: 0)
        
                    Rectangle()
                        .foregroundColor(Style.Color.navigationBarColor)
                        .frame(height: 64)
                    .overlay(
                        HStack() {
                            Image("close")
                            Spacer()
        
                            Text("سفر به سلامت")
                                .font(Style.Font.navigationTitle)
                                .color(Style.Color.darkTextColor)
                                .multilineTextAlignment(.center)
        
                            Spacer()
                            Image("menu")
                        }
                    )
        
                    Spacer()
                }
                .edgesIgnoringSafeArea(.horizontal)
            }
        }
        

        请注意,使用此实现,您将丢失 LargeTitleStyle

        【讨论】:

          猜你喜欢
          • 2020-01-21
          • 1970-01-01
          • 2020-05-28
          • 2021-01-23
          • 2020-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多