簡體   English   中英

SwiftUI 僅更改當前視圖的導航標題顏色

[英]SwiftUI change navigation title color for current view only

我知道我可以使用init全局更改導航欄:

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

我將如何僅針對當前視圖執行此操作? 我只想為當前視圖設置導航標題顏色,而不是應用程序的所有視圖。

最簡單的情況如下(您也可以在某些本地變量中存儲/恢復以前的設置):

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
        })

    }
}

不知道你現在有沒有這個問題。

我已經搜索了這個問題並找到了一篇很棒的文章,您可以將導航欄樣式的設置包裝為視圖修飾符。

檢查此鏈接

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)

這是一個解決方案,它在顯示子視圖時設置屬性,並在子視圖消失時重置它們:

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()
    }
}

演示:

示例的屏幕錄制

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM