Home > Back-end >  SwiftUI: Malfunctioning NavigationBar and TabBar in iOS 15
SwiftUI: Malfunctioning NavigationBar and TabBar in iOS 15

Time:10-03

In SwiftUI, I would like to use a background color for my view while also setting navigationViewStyle to .stack, to force a single-column stack navigation Plus-sized devices.

    var body: some View {
        TabView {
            NavigationView {
                ScrollView {
                    ForEach(0..<100) { _ in
                        Text("Hello, world!")
                            .padding()
                    }
                    .frame(maxWidth: .infinity)
                }
                .navigationTitle("Demo")
//                .background(Color.yellow) // I can do this …
            }
//            .navigationViewStyle(.stack) // … or this, but not both!
            .tabItem {
                Label("Demo", systemImage: "swift")
            }
        }
    }

However, when I do both, the navigation bar won't collapse when I scroll down. Also both the navigation bar and tab bar appear without background.

Screenshot of the simulator showing the issue described above

When I only set the background, but leave out the line that sets the navigationViewStyle, everything looks fine in portrait mode, or smaller devices. But on a Plus-size device in landscape, it looks like this:

Screenshot of the simulator showing the issue described above

So I guess I really can't do this without setting the navigationViewStyle.

What can I do to fix this? Is this a bug that should be fixed by Apple? All help is greatly appreciated.

CodePudding user response:

Use the .navigationViewStyle view modifier on the ScrollView

struct ContentView: View {
    var body: some View {
           TabView {
               NavigationView {
                   ScrollView {
                       ForEach(0..<100) { _ in
                           Text("Hello, world!")
                               .padding()
                       }
                       .frame(maxWidth: .infinity)
                   }
                   .navigationTitle("Demo")
                   .background(Color.yellow)
                   .navigationViewStyle(.stack)

               }
               .tabItem {
                   Label("Demo", systemImage: "swift")
               }
           }
       }
}


Update

I guess, it is a bug. It does not work.

1

If all of your ScrollViews have the same background, use this once on a view.

struct ScrollViewBackground: ViewModifier {
    
    let color: Color
    
    func body(content: Content) -> some View {
        content
            .ignoresSafeArea(edges: .horizontal)
            .onAppear {
                UIScrollView.appearance().backgroundColor = UIColor(color)
            }
    
    }
}

extension View {
    func setBackgroundColor(color: Color) -> some View {
        return self.modifier(ScrollViewBackground(color: color))
    }
}

2

Use introspect to access the underlaying UIScrollView and change its background. You need to also use .ignoresSafeArea(edges: .horizontal) on the ScrollView.

ScrollView {
    Text("Item 2")
}
.introspectScrollView { scrollView in
    scrollView.backgroundColor = UIColor(color.yellow)
}
  • Related