简体   繁体   中英

SwiftUI: How can i change navigation bar style dynamic using custom modifier?

I want to customize my navigation bar in SwiftUI. For that, i created a custom modifier, to set the backgroundColor and textColor and hide the 1px bottom line. The modifier looks something like this:

struct NavigationBarColor: ViewModifier {
    init(backgroundColor: UIColor, tintColor: UIColor, lineHidden: Bool) {
        let coloredAppearance = UINavigationBarAppearance()
        coloredAppearance.configureWithOpaqueBackground()
        coloredAppearance.backgroundColor = backgroundColor
        coloredAppearance.titleTextAttributes = [.foregroundColor: tintColor]
        coloredAppearance.largeTitleTextAttributes = [.foregroundColor: tintColor]
        
        if lineHidden == true {
            coloredAppearance.shadowImage = UIImage()
            coloredAppearance.shadowColor = UIColor.clear
            coloredAppearance.backgroundImage = UIImage()
        }
        
        UINavigationBar.appearance().standardAppearance = coloredAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
        UINavigationBar.appearance().compactAppearance = coloredAppearance
        UINavigationBar.appearance().tintColor = tintColor
    }
    
    func body(content: Content) -> some View {
        content
    }
}

extension View {
    func navigationBarColor(backgroundColor: UIColor, tintColor: UIColor, lineHidden: Bool = false) -> some View {
        self.modifier(NavigationBarColor(backgroundColor: backgroundColor, tintColor: tintColor, lineHidden: lineHidden))
    }
}

I use it on my ContentView() like this:

var body: some View {
        NavigationView {
            NavigationLink(destination: EventDetailView()) {
                Text("Go to Detail Page")
            }
            .navigationTitle("Master")
            .navigationBarColor(backgroundColor: .secondarySystemBackground, tintColor: .black, lineHidden: true)
        }
    }

It works as i expected, but when i set the modifier different on my detailView, the navigationBarAppearance is not updated. My DetailView looks like this:

var body: some View {
        Text("Details")
            .navigationTitle("Detail Page")
            .navigationBarTitleDisplayMode(.inline)
            .navigationBarColor(backgroundColor: .systemRed, tintColor: .white, lineHidden: true)
    }

What can I change so that the style of the navigation bar changes when I go to the details page? Everhting an idea?

Use this which is a little different than your solution.

struct NavigationBarModifier: ViewModifier {
    
    var backgroundColor: UIColor?
    
    init(backgroundColor: UIColor, tintColor: UIColor, lineHidden: Bool) {
        self.backgroundColor = backgroundColor
        let coloredAppearance = UINavigationBarAppearance()
        coloredAppearance.configureWithTransparentBackground()
        coloredAppearance.backgroundColor = .clear
        coloredAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        coloredAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
        
        if lineHidden == true {
            coloredAppearance.shadowImage = UIImage()
            coloredAppearance.shadowColor = UIColor.clear
            coloredAppearance.backgroundImage = UIImage()
        }
        
        UINavigationBar.appearance().standardAppearance = coloredAppearance
        UINavigationBar.appearance().compactAppearance = coloredAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
        UINavigationBar.appearance().tintColor = .white
        
    }
    
    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, tintColor: UIColor, lineHidden: Bool) -> some View {
        self.modifier(NavigationBarModifier(backgroundColor: backgroundColor, tintColor: tintColor, lineHidden: lineHidden))
    }
    
}

You may change the appears of the navigation bars.


Credit goes to https://filipmolcik.com/navigationview-dynamic-background-color-in-swiftui/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM