Search code examples
iosswiftswiftuiswiftui-tabview

SwiftUI TabView prevent swipe bounce


I have a TabView with .tabViewStyle(PageTabViewStyle())

I am trying to prevent the first view and last view from bouncing. So basically, prevent scrolling horizontally.

struct ContentView: View {
    @State var stop = false
    var body: some View {
        TabView {

            Text("Example 1")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(GeometryReader {
                    // read and store origin (min X) of page
                    Color.red.preference(key: ViewOffsetKey.self,
                                         value: $0.frame(in: .global).minX)
                }).contentShape(Rectangle())

            Text("Example 2")
            Text("Example 3")

        }
        .tabViewStyle(PageTabViewStyle())
        .onPreferenceChange(ViewOffsetKey.self) {
            
            if $0 > 0.0 {
                // Off screen stop scrolling horizontal
                print("off screen")
                stop = true
            } else {
                stop = false
            }

            print("Offset >> \($0)")
        }.gesture(
            DragGesture(minimumDistance: 10)
              .onEnded { value in
                print(value)
              }
              .onChanged { value in
               print(value)
              }
        )
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}


Solution

  • You Have to add below line in .onAppear Method.

    .onAppear(perform: {
                UIScrollView.appearance().bounces = false
            })
    

    Here is the full code.

    struct ContentView: View {

    @State var stop = false
    var body: some View {
        TabView {
            Text("Example 1")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(GeometryReader {
                    // read and store origin (min X) of page
                    Color.red.preference(key: ViewOffsetKey.self,
                                         value: $0.frame(in: .global).minX)
                }).contentShape(Rectangle())
            
            Text("Example 2")
            Text("Example 3")
        }
        .onAppear(perform: {
            UIScrollView.appearance().bounces = false
        })
        .tabViewStyle(PageTabViewStyle())
        .onPreferenceChange(ViewOffsetKey.self) {
            
            if $0 > 0.0 {
                // Off screen stop scrolling horizontal
                print("off screen")
                stop = true
            } else {
                stop = false
            }
            
            print("Offset >> \($0)")
        }.gesture(
            DragGesture(minimumDistance: 10)
                .onEnded { value in
                    print(value)
                }
                .onChanged { value in
                    print(value)
                }
        )
    }
    

    }