4

I am using a TabView with a page style to display scrollable cards that snap into place. I've placed the TabView in a HStack with spacers on each end which centers the TabView. The TabView also has a width of 80% of the HStack.

I'd love to have the TabView content extend beyond the bounds to be edge to edge on the screen while also keeping the centring and 80% width. Here's an example of Apple doing this in the App Store.

Apple App Store Example

Here is what I have so far.

My Cards Example

While the content is centred and has an 80% width, the content is cut off beyond the TabView bounds. The second card should be visible like in the Apple examples and the content should be edge to edge.

Here is the code I have so far.

struct CardsView: View {
    
    var body: some View {
        VStack {
            SectionHeaderView()
            
            GeometryReader { geometry in
                HStack(spacing: 0) {
                    Spacer()
                    Group {
                        TabView {
                            CardView()
                                .tag(0)
                            
                            CardView()
                                .tag(1)
                            
                            CardView()
                                .tag(2)
                        }
                            .frame(width: geometry.size.width * 0.8, height: 150)
                            .tabViewStyle(.page(indexDisplayMode: .never))
                    }
                    Spacer()
                }
            }
                .frame(height: 150)
        }
            .padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0))
    }
}

struct CardView: View {
    
    var body: some View {
        Group {
            Group {
                VStack {
                    HStack {
                        Text("Testing")
                        Spacer()
                    }
                    Spacer()
                }
            }
                .padding()
                .background(Color.ui.backgroundCell)
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                .cornerRadius(kCornerRadiusViews)
        }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
            .tag(0)
    }
}

To me, it seems like there is some clipping being done on the TabView but to my knowledge, it doesn't seem like there is an equivalent to clipsToBounds = false in SwiftUI. I am not sure how to remove this clipping.

Any help would be very appreciated.

  • Welcome to StackOverflow! A 'TabView' is not going to do this for you. You need to put them in a horizontal 'ScrollView'. – Yrb Nov 02 '21 at 13:07

2 Answers2

0

It should be what you would like to have:

Click to see the Swiper in action

From your code, I removed some parts like (Spacer(), .frame(), ...) and I moved GeometryReader to the CardView().

struct CardsView: View {
    var body: some View {
        VStack {
            SectionHeaderView()

            HStack {
                TabView {
                    CardView()
                        .tag(0)
                    
                    CardView()
                        .tag(1)
                    
                    CardView()
                        .tag(2)
                }
                .tabViewStyle(.page(indexDisplayMode: .never))
            }
        }
        .padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0))
    }
}

struct CardView: View {
    
    var body: some View {
        
        GeometryReader { geometry in
            Group {
                VStack {
                    HStack {
                        Text("Testing")
                        Spacer()
                    }
                    Spacer()
                }
                .padding()
                .background(Color.ui.backgroundCell)
                .cornerRadius(kCornerRadiusViews)
            }
            .frame(width: geometry.size.width * 0.8, height: 150)
            .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
        }
    }
}
Boopy
  • 309
  • 3
  • 5
-2

You just need to change the parameters at the bottom of your CardView view - the leading and trailing margins are too wide.

Try this, it should be exactly what you are looking for (I tested and it works):

.padding(EdgeInsets(top: 0, leading: 2, bottom: 0, trailing: 2))   // Reduce leading and trailing insets
HunterLion
  • 3,496
  • 1
  • 6
  • 18
  • The edge insets don't resolve the issue or address what OP is asking for. This will just change the content inset, but won't resolve the clipping issue. – Sam Spencer Mar 07 '22 at 18:09