Reputation: 65429
Using a TabView as a pageviewer by using .tabViewStyle(PageTabViewStyle())
works fine, but trying to let it run from edge to edge by applying edgesIgnoringSafeArea
does not seem to work.
What am I missing here?
struct ContentView: View {
let colors: [Color] = [.red, .green, .blue]
var body: some View {
TabView {
ForEach(0...2, id: \.self) { index in
Rectangle()
.fill(colors[index])
}
}
.tabViewStyle(PageTabViewStyle())
.edgesIgnoringSafeArea(.all)
}
}
Adding another .edgesIgnoringSafeArea(.all)
to the Rectangle
or ForEach
also doen't work.
Note that all these questions are different because they do not use use PageTabViewStyle()
:
Their solution (adding edgesIgnoringSafeArea(.all)
) doesn't work in this case.
Upvotes: 36
Views: 12570
Reputation: 127
Wrapping TabView in a ScrollView as suggested by @kimigori here works but causes the page dots to become scrollable. To fix them in place use a horizontal ScrollView.
This is a re-usable PageView that works with ignoresSafeArea(_:edges:)
:
struct PageView<Content: View>: View {
let content: () -> Content
var body: some View {
GeometryReader { geo in
ScrollView(.horizontal) {
TabView {
content()
}
.frame(width: geo.size.width, height: geo.size.height)
.tabViewStyle(PageTabViewStyle())
}
}
}
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
}
Example:
struct TestPageView: View {
var body: some View {
PageView {
ForEach(0...2, id: \.self) { index in
ZStack {
Rectangle()
.fill([.red, .green, .blue][index])
Text("Page \(index + 1)")
}
}
}
.ignoresSafeArea()
}
}
Upvotes: 7
Reputation: 375
Found this by accident, so hope it works for others. Works for me on iOS15 and 16, YMMV.
Add a background color to the TabView:
TabView(selection: $index) {
YourTabViewContent
.ignoresSafeArea()
}
.background(Color.background)
.tabViewStyle(.page(indexDisplayMode: .never))
.edgesIgnoringSafeArea(.all)
Upvotes: 7
Reputation: 91
Just use:
.ignoresSafeArea(edges:[.top,.bottom])
I suppose that TabView
can't ignore leading and trailing, which is included in .all
. However, if you manually set .top
and .bottom
it works fine.
Upvotes: 1
Reputation: 133
Update in SwiftUI 3.0:
TabView {
ForEach(0...2, id: \.self) { index in
Rectangle()
.fill(colors[index])
}
.ignoresSafeArea()
}
.tabViewStyle(PageTabViewStyle())
.edgesIgnoringSafeArea(.all)
Upvotes: 10
Reputation: 1684
I worked around this annoying issue by "extending" the TabView
's height and "shifting" it towards the top by the same amount:
struct ContentView: View {
var body: some View {
let yExtension: CGFloat = 50
GeometryReader { g in
TabView {
Color.red.overlay(Text("1"))
Color.green.overlay(Text("2"))
Color.blue.overlay(Text("3"))
Color.orange.overlay(Text("4"))
}
.frame(width: g.size.width, height: g.size.height + yExtension)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))
.font(Font.title.bold())
}
.offset(y: -yExtension)
.edgesIgnoringSafeArea(.all)
}
}
Tested on Xcode 12.4, iOS 14.4:
Upvotes: 3
Reputation: 977
struct ContentView: View {
let colors: [Color] = [.red, .green, .blue]
var body: some View {
ScrollView {
TabView {
ForEach(0...2, id: \.self) { index in
Rectangle()
.fill(colors[index])
}
}
.frame(
width: UIScreen.main.bounds.width ,
height: UIScreen.main.bounds.height
)
.tabViewStyle(PageTabViewStyle())
}
.edgesIgnoringSafeArea(.all)
}
}
Upvotes: 40
Reputation: 258117
Here is a maximum what I've got... anyway I assume that originally it is a bug and worth submitting feedback to Apple.
Tested with Xcode 12b
struct TestPagingStyle: View {
let colors: [Color] = [.red, .green, .blue]
var body: some View {
ZStack {
Color.black.overlay(
GeometryReader { gp in
TabView {
ForEach(0..<3, id: \.self) { index in
Text("Hello, World \(index)")
.frame(width: gp.size.width, height: gp.size.height)
.background(colors[index])
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
}
)
}.edgesIgnoringSafeArea(.all)
}
}
Upvotes: 6