2

How do we get a background image for the ContentView but not its subviews AND retain the behavior of scrollable content disappearing under the NavBar?

I found that if I added the background as a modifier to a List or ScrollView, it didn't change the background on subviews (ex. DetailView) but scrollable content no longer disappeared under the navbar and the NavBar title stayed in place (see pic #2). But if I modified the NavigationView, it restored the behavior of scrollable content disappearing under the navbar (see pic #3) but it also changed the background on all subviews (see pic #4)

I tried a ZStack with Image("MoonPhoto") and then the List

But mostly I tried different placements of this ViewModifier struct:

struct BackgroundImage: ViewModifier {
    func body(content: Content) -> some View {
        content
            .opacity(0.8)
            .background(Image("history-in-hd-e5eDHbmHprg-unsplash")
            .resizable()
            .scaledToFill())
    }
}

And here is the main body of ContentView:

     var body: some View {
        NavigationView {
            List(missions) { mission in
                NavigationLink(destination: MissionView(mission: mission, astronauts: self.astronauts))
                {
                    Image(mission.image)
                        .resizable()
                        .scaledToFit()
                        .frame(width: 50, height: 50)

                    VStack(alignment: .leading) {
                        Text(mission.displayName)
                            .font(.headline)
                        Text(self.showCrew ? self.crewList(mission: mission) : mission.formattedLaunchDate)
                    }
                }
                .navigationBarTitle("Moonshot")
            }
            .navigationBarTitle("Moonshot")
            .navigationBarItems(leading:
                Button(self.showCrew ? "Show Launch date" : "Show crew") {
                    self.showCrew.toggle()
                }
            )
            .modifier(BackgroundImage()) //Modifying List
        } //If you move the above modifier here, the image shows an all subviews too
    }
}

screenshots 1 and 2

screenshots 3 and 4

Steve Robertson
  • 209
  • 5
  • 12
  • I cannot answer your question now. But I suggest you to read this: https://stackoverflow.com/questions/57128547/swiftui-list-color-background , before your further search. – E.Coms Nov 04 '19 at 23:44
  • That would be great if you can take a look. I tried different things from the article you linked to but they don't seem to be the answer. Even one of their answers shows the need for the navbar - otherwise scrolling content goes past the safe area and doesn't look good. – Steve Robertson Nov 05 '19 at 02:22

1 Answers1

2

Major issue as I observe is about .large DisplayMode for navigationBarTitle modifier. I've found a solution appropriate for me, but still it's like a workaround. Anyway, you can consider it as a temporary solution.

The main idea is to wrap List in VStack and use .inline display mode. Hope, this would help somehow.

Here how it looks (works for Dark Mode as well)

list with background

import SwiftUI

struct BackgroundImage: ViewModifier {
    func body(content: Content) -> some View {
        content
            .opacity(0.8)
            .background(Image("history-in-hd-e5eDHbmHprg-unsplash")
            .resizable()
            .scaledToFill())
    }
}


struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                List (1...20, id: \.self) { value in
                    NavigationLink(destination: Text("Details \(value)")) {
                        Text("\(value)")
                    }
                }
            }
            .modifier(BackgroundImage())
            .navigationBarTitle("Title", displayMode: .inline)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • This works with only one small (but acceptable to me) tradeoff: The App title starts inline instead of animating to that position upon scrolling. – Steve Robertson Nov 05 '19 at 19:23