4

This ought to be straightforward enough, but I cannot find out how to place a background behind a NavigationStack. With NavigationView, it was simply a matter of embedding in a ZStack with the background view called before the NavigationView (as described in an older post: How change background color if using NavigationView in SwiftUI?) The same technique does not work for me with NavigationStack. Here's what I have:

   struct MyAngularGradient: View {
    var body: some View {
        ZStack {
            AngularGradient(gradient: Gradient(colors: [.red, .orange , .yellow, .green, .cyan, .blue, .indigo, .purple, .red]), center: .leading)
            AngularGradient(gradient: Gradient(colors: [.red, .orange , .yellow, .green, .cyan, .blue, .indigo, .purple, .red]), center: .leading)
                .offset(x: -8)
        }
        .ignoresSafeArea()
    }
}

var body: some View {
            ZStack{
                MyAngularGradient()
                NavigationStack {
                  ...
                }
                 .navigationViewStyle(.stack)
             } // end ZStack

FYI, I've used the same MyAngularGradient()in other apps (with NavigationView) Any ideas? Thanks.

2 Answers 2

7

The closest I've managed to get so far is this:

struct MyView: View {

    var body: some View {
        NavigationStack {
            ZStack {
                Color.pink.ignoresSafeArea()

                List {
                    NavigationLink("Hello") {
                        Text("Hello")
                    }
                }
                .navigationTitle("Title")
            }
        }
        .scrollContentBackground(.hidden)
    }

}

Which is somewhat dissatisfying for the following reasons:

  1. When you scroll up the navigation bar appears, as expected, but ruins the effect imo.

I guess you can experiment changing this in a limited way using UINavigationBarAppearance() by updating it in the constructor of the view.

Non-scrolled image of the above Scrolled version of the above

  1. You can't apply a background to the whole app if you have multiple NavigationStackView based views in a TabView. (My example above was in a TabView)

  2. When a new view is pushed on the stack the custom background disappears.

  3. Only works on iOS 16+ due to the .scrollContentBackground(.hidden) modifier.

  4. Does not work if you use ForEach to populate the List. Interestingly if you debug the hierarchy with and without the ForEach you'll see that SwiftUI adds a new view controller which is opaque in the case of ForEach.

1
  • 2
    Thank you brindy for taking the time to answer. I tried your suggestion with immediate but limited success. I will keep experimenting, and if/when I get the effect I'm hoping for, I will be sure to update this post. In the meantime, thanks for getting me headed in (what I think is) the right direction.
    – Hyoryusha
    Dec 8, 2022 at 8:24
0

You can just apply .background to the main content.

  • Use .frame to extend the size of the main content to the full screen size, if necessary.
  • A ZStack is not needed.
NavigationStack {
    Text("NavigationStack")
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(MyAngularGradient())
}
.navigationViewStyle(.stack)

Note that the safe area insets are ignored by default when the background is set in this way, see background(_:ignoresSafeAreaEdges:)

Screenshot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.