I am trying to implement a detail view which is linked from a navigation view.
In this detail view, there is a default nav bar on top with a back button.
But the bar only show some color when I scroll up. I have no idea why.
Initially, the nav bar doesn’t have background either when it’s scrolling or not.
So I created an init() method for setting up the style.
init(fruit: Fruit) {
self.fruit = fruit
if #available(iOS 15.0, *) {
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithDefaultBackground()
UINavigationBar.appearance().standardAppearance = navigationBarAppearance
UINavigationBar.appearance().compactAppearance = navigationBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
}
}
The Body View is a Navigation View on the outside and scroll view inside.
** For anyone wonder why I set the navbar to hidden in the VStack, is because if I don’t hide it, there would be some huge space above the image. (I have no idea why)
** Updated Code **
I updated my code which use the Opaque background.
But it seems like none of those config are visible.
init(fruit: Fruit) {
self.fruit = fruit
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
UINavigationBar.appearance().standardAppearance = navBarAppearance
}
var body: some View {
NavigationView {
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .center, spacing: 20) {
// HEADER
FruitHeaderView(fruit: fruit)
VStack(alignment: .leading, spacing: 20) {
// TITLE
Text(fruit.title)
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(fruit.gradientColors[1])
} //: VSTACK
.padding(.horizontal, 20)
.frame(maxWidth: 640, alignment: .center)
} //: VSTACK
.navigationBarHidden(true)
} //: SCROLL
.edgesIgnoringSafeArea(.top)
} //: NAVIGATION
.navigationBarTitle(fruit.title, displayMode: .inline)
.navigationViewStyle(StackNavigationViewStyle())
}
*** Solution ***
It turns out I have to put the configurations code of the nav bar in the parent view. During init().
Can anyone explain why this on the parent view? Or if I want different style in parent and child what should I do?
init() {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
UINavigationBar.appearance().standardAppearance = navBarAppearance
}
var body: some View {
NavigationView {
List {
ForEach(fruits.shuffled()) { item in
NavigationLink {
FruitDetailView(fruit: item)
} label: {
FruitRowView(fruit: item)
.padding(.vertical, 4)
}
}
}
.listStyle(.plain)
.navigationTitle("Fruits")
} //: NAVIGATION
}
5
Answers
use this code in viewWillAppear
Use my extension:
call it in viewDidAppear or viewDidLoad , in your case set background to clear… How to use:
You need opaque appearance, because
default
one meanssystem-selected-by-design
which is changed from version to version.Tested with Xcode 13.3 / iOS 15.4 (in ContentView.init)
Note: onAppear is too late to inject above code, the appearance settings are applied on objects created after it, and onAppear is called after NavigationView created. So use it either in init, or anywhere else, but before view created.
This worked for me –
In Xcode 14.3 the solutions above did not work but the following approach proved to be successful and resolved the issue for me.