Combining Horizontal and Vertical PageTabViews

Hey everyone!

@CalStark and I are having trouble with some PageTabView issues in Swift UI. Could anyone please take a look? :grinning_face_with_smiling_eyes:

We’re currently making an app with the following structure : a horizontal PageTabView with 3 views, of which the first is actually a Vertical PageTabView made of three other views (using a 90° rotation trick we found online).

So we managed to make this “inverted L” shaped navigation work but now we are encountering an issue with the UIScrollView bounces animations.

UIScrollView.appearance().bounces = false

In the piece of code above, we need “bounces = false” to swipe from views 1,2 or 3 to views A and B.

But once we’re inside A,B we need “bounces = true” for UI design reasons specific to views A and B.

So we put an .onAppear() { } modifier on the views A and B that change bounces to true.

Luckily, “bounces == true” in A,B still allows to go back to 1,2,3.

However, once we’re back in 1,2,3, we need to have “bounces == false” again (to be able to swipe back to A,B)

The problem is that for some reason, it appears that our code that sets “bounces == false” in 1,2,3 doesn’t work when we come back: we’re stuck in 1,2,3, and cannot swipe back to A,B again, so we assume that bounces is in fact still true in the system.

Below you’ll find our code, if anyone can help we shall be forever grateful :slight_smile:

Horizontal PageTabView :

 struct HorizontalNav: View {
    
    @State private var selection = 0

    var body: some View {
        
        // MARK: - Core Nav View
        
        NavigationView {
            
            ZStack {
                
                // MARK: - Tab View Page Style
    
                    ScrollView(.init()) { //
                        
                        TabView(selection: $selection) {
                            
                            VerticalNav()
                                .tag(0)
                                .onAppear(perform: {
                                    UIScrollView.appearance().bounces = false
                                })
                                
                            Color.green
                                .tag(1)
                                .onAppear(perform: {
                                    UIScrollView.appearance().bounces = true
                                })
                            
                            Color.yellow
                                .tag(2)
                                .onAppear(perform: {
                                    UIScrollView.appearance().bounces = true
                                })
                              
                        }
                        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
                
                    }
                   
                // MARK: - TabBarView
                
            }.navigationBarHidden(true)
            .ignoresSafeArea()
        
        }.onAppear(perform: {
            UIScrollView.appearance().bounces = false
        })
        
    }
}

Vertical PageTabView :

struct VerticalNav: View {
    
    let colors: [Color] = [
            .blue, .purple, .pink
        ]
    
    var body: some View {
        
        ZStack {
            GeometryReader { proxy in
                
                        TabView {
                            ForEach(colors, id: \.self) { color in
                                color // Your cell content
                            }
                            .rotationEffect(.degrees(-90)) // Rotate content
                            .frame(
                                width: proxy.size.width + 100,
                                height: proxy.size.height
                            )
                           
                        }
                        .frame(
                            width: proxy.size.height, // Height & width swap
                            height: proxy.size.width
                        )
                        .rotationEffect(.degrees(90), anchor: .topLeading) // Rotate TabView
                        .offset(x: proxy.size.width) // Offset back into screens bounds
                        .tabViewStyle(
                            PageTabViewStyle(indexDisplayMode: .never)
                        )
                        
            }
        }.ignoresSafeArea()
        
    }
}
1 Like

Why do you have both views inside a ZStack?
It doesn’t look like it necessary

1 Like

Hey Mikaela, thanks for your response !

In HorizontalNav, there’s a ZStack because we want to add a custom TabBar above it later.
As for VerticalNav, you’re 100% right the ZStack is unnecessary, I removed it.

Unfortunately our issue remains :frowning:

1 Like

Hey everyone,
Little update regarding this issue : after updating to iOS 15 and Xcode 13, the code actually works great and there’s no problem with navigation!
So here you go… Thanks Apple :slight_smile:

2 Likes