I'm trying to set a custom gradient for the navigation .toolbarBackground but anytime I run its only using the first color from the LinearGradient.
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Menu {
// MARK: 2 Actions
// 1. logout
// 2. Delete Account
Button("Logout",action: logOutUser)
Button("Delete Account",role: .destructive,action: deleteAccount)
} label: {
Image(systemName: "slider.horizontal.3")
.rotationEffect(.init(degrees: 90))
.tint(.white)
.scaleEffect(0.8)
}
}
}
.navigationBarTitleDisplayMode(.inline)
.navigationTitle("My Garden")
.toolbarColorScheme(.dark, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarBackground(LinearGradient(gradient: Gradient(colors: [Color("Green1"), Color("Green2")]),startPoint: .bottomLeading,endPoint: .topTrailing))
I came across the same issue lately and according to a blog post by Sarunw this is simply not possible as of iOS 16:
In the current beta, we can't use other
ShapeStyle
likeLinearGradient
.I have filed a bug report and will update the post once I know it is the intended behavior or a bug.
→ https://sarunw.com/posts/swiftui-navigation-bar-color/#basic-usage
If you don’t want to wait for iOS 17 to maybe fix this issue, you can fall back to UIKit and use the UINavigationBarAppearance
instead and use a gradient image. I guess you could even create the gradient image in code, but I simply ended up putting the gradient image into the asset catalog (default, without slicing) and feed it to the NavBar as backgroundImage
.
There are quite a few tutorials out there showing this way, like this, this or this video. I the end they all end up with some form of this code:
struct MainNavigationBar: ViewModifier {
init() {
let appearance = UINavigationBarAppearance()
// Custom gradient background
appearance.backgroundImage = UIImage(named: "NavigationBarBackground")
// Apply custom styling to all bar states
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance
// Custom button color tinting
// (buggy and not working for me for some reason)
UINavigationBar.appearance().tintColor = .white
}
func body(content: Content) -> some View {
content
}
}
Now you can use this modifier on a NavigationStack
to attach this style to the view and all of the subviews.
NavigationStack {
// Your Content
}
.modifier(MainNavigationBar())