I want a TabView that uses a PageTabViewStyle with each individual screen having a different background colour that fills the entire vertical space available (i.e. extended into the safe areas).
TabView(selection: $selection) {
VStack {
Text("screen 1")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
VStack {
Text("screen 2")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.red)
}.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
However, it looks like this:
And after I scroll to the bottom:
The white colour can be changed if I set a background colour for the TabView itself, which would be fine if each screen used the same background colour. Is there any way for individual screens within the TabView to have a unique background colour set that fills the entire screen?
Normally I wouldn't suggest GeometryReader
, but this doesn't look like intended behavior on Apple's part. The key is expanding the background modifier color to a large enough height so that you can't see the white background behind the tab.
Thank you, Asperi, for sharing the link to a similar question for inspiration:
https://stackoverflow.com/a/62596307/12299030
struct ContentView: View {
@State private var selection: Int = 0
var body: some View {
GeometryReader { geo in
TabView(selection: $selection) {
VStack {
Text("Screen 1")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(
EmptyView()
.frame(minHeight: 2 * geo.size.height)
.background(Color.green)
)
.tag(0)
VStack {
Text("Screen 2")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(
EmptyView()
.frame(minHeight: 2 * geo.size.height)
.background(Color.red)
)
.tag(1)
}.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
}
}
Using an EmptyView
combined with a set minimum height of 2 times the current height ensures that the user can scroll up and down, reaching the bounce-back distance, and not see a white background. Put any background you'd like on this view.
You may be able to swap out EmptyView
with whatever you'd like, but that was the first thing that came to mind. I added .tag()
and selection
so that ContentView
can be ran on its own in case you'd like to experiment.