SwiftUI如何仅为当前视图更改导航栏标题颜色

3

我知道可以使用init全局更改导航栏:

init() {
    UINavigationBar.appearance().largeTitleTextAttributes = [
        .foregroundColor: UIColor.red
    ]
}

我只想为当前视图设置导航栏标题颜色,而不是整个应用程序中的所有视图。如何做到这一点?

3个回答

2
最简单的情况如下(您还可以在某些本地变量中存储/恢复先前的设置):
var body: some View {
    NavigationView(){
        List {
            // Some content is here
        }
        .navigationBarTitle("Title")
        .onAppear(perform: {
            UINavigationBar.appearance().largeTitleTextAttributes = [
                .foregroundColor: UIColor.red
            ]
        })
        .onDisappear(perform: {
            UINavigationBar.appearance().largeTitleTextAttributes = nil
        })

    }
}

1

不确定你现在是否遇到这个问题。

我已经搜索了这个问题,并找到了一篇很棒的文章,你可以将导航栏样式的设置包装成一个视图修饰符。

点击这里链接查看。

struct NavigationBarModifier: ViewModifier {
        
    var backgroundColor: UIColor?
    var titleColor: UIColor?
    
    init(backgroundColor: UIColor?, titleColor: UIColor?) {
        self.backgroundColor = backgroundColor
        let coloredAppearance = UINavigationBarAppearance()
        coloredAppearance.configureWithTransparentBackground()
        coloredAppearance.backgroundColor = backgroundColor
        coloredAppearance.titleTextAttributes = [.foregroundColor: titleColor ?? .white]
        coloredAppearance.largeTitleTextAttributes = [.foregroundColor: titleColor ?? .white]
        
        UINavigationBar.appearance().standardAppearance = coloredAppearance
        UINavigationBar.appearance().compactAppearance = coloredAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
    }
    
    func body(content: Content) -> some View {
        ZStack{
            content
            VStack {
                GeometryReader { geometry in
                    Color(self.backgroundColor ?? .clear)
                        .frame(height: geometry.safeAreaInsets.top)
                        .edgesIgnoringSafeArea(.top)
                    Spacer()
                }
            }
        }
    }
}

extension View {
 
    func navigationBarColor(backgroundColor: UIColor?, titleColor: UIColor?) -> some View {
        self.modifier(NavigationBarModifier(backgroundColor: backgroundColor, titleColor: titleColor))
    }

}

之后,就像这样应用:

.navigationBarColor(backgroundColor: .clear, titleColor: .white)

0
这里有一个解决方案,在子视图显示时设置属性,当子视图消失时重置它们:
import SwiftUI

struct ExampleView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: NestedView()) {
                Label("Navigate", systemImage: "folder")
            }
            .navigationTitle("Home")
        }
        // This is important, it doesn't work without it.
        .navigationViewStyle(.stack)
    }
}

struct NestedView: View {
    var body: some View {
        ZStack {
            NavigationControllerAccessor(viewWillAppear: { nav in
                nav.navigationBar.largeTitleTextAttributes = [
                    .foregroundColor: UIColor.red
                ]
            }, viewWillDisappear: { nav in
                nav.navigationBar.largeTitleTextAttributes = nil
            })
            Text("In nested view")
        }
        .navigationTitle("Nested")
    }
}

struct NavigationControllerAccessor: UIViewControllerRepresentable {
    var viewWillAppear: (UINavigationController) -> Void
    var viewWillDisappear: ((UINavigationController) -> Void)? = nil

    private let proxyController = ViewController()

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationControllerAccessor>) -> UIViewController {
        proxyController.viewWillAppearCallback = viewWillAppear
        if let viewWillDisappear = viewWillDisappear {
            proxyController.viewWillDisappearCallback = viewWillDisappear
        }
        return proxyController
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationControllerAccessor>) {}

    private class ViewController: UIViewController {
        var viewWillAppearCallback: (UINavigationController) -> Void = { _ in }
        var viewWillDisappearCallback: (UINavigationController) -> Void = { _ in }

        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            if let nav = navigationController {
                viewWillAppearCallback(nav)
            }
        }

        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            if let nav = navigationController {
                viewWillDisappearCallback(nav)
            }
        }
    }
}

struct ExampleView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleView()
    }
}

演示:

Screen recording of example


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接