4

I'm creating a vertical paging view via TabView following this

Everything is perfect except the strange right margin as highlighted in pic below.

Here is the code I use. Appreciate it if anyone could point out the root cause.

enter image description here

import SwiftUI

fileprivate struct VCompatibleTabView<Content: View>: View {
    let proxy: GeometryProxy
    let content: Content
    
    init(proxy: GeometryProxy, @ViewBuilder content: () -> Content) {
        self.proxy = proxy
        self.content = content()
    }
    
    var body: some View {
        if #available(iOS 15.0, *) {
            // Credit to Gary Tokmen for this bit of Geometry Reader code: https://blog.prototypr.io/how-to-vertical-paging-in-swiftui-f0e4afa739ba
            TabView {
                content
                .rotationEffect(.degrees(-90)) // Rotate content
                .frame(
                    width: proxy.size.width,
                    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)
            )
        } else {
            ScrollView(.vertical, showsIndicators: false) {
                LazyVStack(spacing: 0) {
                    content
                }
            }
            .frame(
                width: proxy.size.width,
                height: proxy.size.height)        }
    }
}

struct BBYouView: View {

    var body: some View {
        ZStack {
            GeometryReader { proxy in
                VCompatibleTabView(proxy: proxy) {
                    ForEach(0..<3, id: \.self) { item in
                        Rectangle().fill(Color.pink)
                        .frame(
                            width: proxy.size.width,
                            height: proxy.size.height
                        )
                    }
                }
            }
        }
        .background(Color.yellow)
    }


}
LiangWang
  • 8,038
  • 8
  • 41
  • 54
  • Does this answer your question? [SwiftUI TabView with PageTabViewStyle in Landscape on device with safeArea adding odd leading edge inset](https://stackoverflow.com/questions/69563644/swiftui-tabview-with-pagetabviewstyle-in-landscape-on-device-with-safearea-addin) – Yrb Feb 25 '22 at 14:07
  • Hey...any update on this issue? – Dario Pellegrini Dec 06 '22 at 09:26

2 Answers2

2

Horizontal/Vertical paging in iOS 17

From iOS 17, you don't need to do the hack of rotating the tab view and you can enable the paging behavior by applying the following modifier on the ScrollView:

.scrollTargetBehavior(.paging)

So anything inside the ScrollView like a simple ForEach inside a stack would be paging as desired. This works for both horizontal and vertical scrollviews.

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
1

There is iOS17 modifier .scrollTargetBehavior(.paging), for older versions this hack should work:

import SwiftUIIntrospect

GeometryReader { proxy in
    ScrollView {
        LazyVStack(spacing: 0) {
            ForEach([Color.red, Color.green, Color.blue], id: \.self) { color in
                color.frame(proxy.size)
            }
        }
    }
    .introspect(.scrollView, on: .iOS(.v15, .v16, .v17)) { sv in
        sv.isPagingEnabled = true
    }
}
Oleksandr
  • 169
  • 10