16

Is there a way I can specify the background color of the view used to display a sheet in SwiftUI? I know I can set .background on my view, but on iPhone X that doesn't affect the safe area. I also could use .edgesIgnoringSafeArea to fill the area, but I'd prefer not to mess with that.

enter image description here

2
  • Maybe you need to rephrase your question. .background would solve your problem, but you're really looking for a good way to include the safe area in the background color. Commented Aug 1, 2019 at 0:11
  • 1
    Hmm, yeah wasn't sure how to phrase it... I want to set the backgroundColor of the ViewController that's used to present SwiftUI modals. Commented Aug 1, 2019 at 0:24

5 Answers 5

19

One more solution is to use a ZStack:

.sheet(isPresented: $showingCustomView) {
    ZStack {
        Color.black.edgesIgnoringSafeArea(.all)
        CustomView()
    }
}
Sign up to request clarification or add additional context in comments.

Comments

11

In the end you need to deal with edgesIgnoringSafeArea since you need to go beyond the safe area (you'd have to do the same in UIKit). The important thing is, that you only ignore the safe area for your background. So in terms of SwiftUI, you only need to apply edgesIgnoringSafeArea to the view you pass to background:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("hey there")
            Text("Another line")
        }.background(Color.blue.edgesIgnoringSafeArea(.all))
    }
}

However, this requires that the view you use background on already requests all of the available space (which is not the case in my sample code above), since background only draws a background of the view and does not fill the screen by itself. If that's not the case for you, you need to use e.g. a ZStack as shown in your answer.

Comments

5

Messed with this some more and landed on this solution

struct BackgroundFillView<Content: View>: View {
    let backgroundColor: Color
    let content: () -> Content

    var body: some View {
        ZStack {
            self.backgroundColor.edgesIgnoringSafeArea(.all)
            self.content()
        }
    }
}

Comments

4

You need to set presentationBackground (only works for iOS 16.4+)

public extension View {
    // Example: .apply { v in return v.padding(20) }
    func apply<V: View>(@ViewBuilder _ block: (Self) -> V) -> V { block(self) }
}


#Preview {
    ZStack {
        Color.red.ignoresSafeArea()
    }
    .sheet(isPresented: .constant(true)) {
        YourAwesomeSheetView()
            .apply {
                if #available(iOS 16.4, *) {
                    $0.presentationBackground(Color.blue)
                } else {
                    $0
                }
            }
    }
}

Comments

-1

I find this way to resolve that by Introspect, you can find this on https://github.com/siteline/SwiftUI-Introspect and then in your SwiftUI view to do this:

YourUIViewController().introspectViewController
{ (viewController) in
 viewController.view.backgroundColor = .red
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.