Any update on disabling the 2 finger swipe on `TabView` in SwiftUI when using page style?
I have been facing the same issue and not able to disable it for TabView in SwiftUI. But I changed my implementation using ScrollView to implement the TabView effect in one of my App.
# Implementation of TabView using ScrollView
```swift
struct TabContentView: View {
private var views: [AnyView] = []
@State private var currentIndex: Int = 0
init() {
self.views = [
// The below are your components
AnyView(Page1()),
AnyView(Page2()),
AnyView(Page3())
]
}
var body: some View {
GeometryReader { proxy in
ScrollViewReader { value in
TabNavigationBar(
currentIndex: $currentIndex,
pageCount: views.count
)
.padding()
.background(.green)
ScrollView(.horizontal) {
HStack {
ForEach(0..<views.count, id: \.description) { index in
self.views[index]
.id(index) // We need to set the id to identify the view when trying to scroll programatically
.frame(width: proxy.size.width)
}
}
}
.scrollDisabled(false) // To disable scroll
.transition(.slide)
.onChange(of: self.currentIndex) { oldValue, newValue in
withAnimation {
value.scrollTo(newValue) // To programatically scroll to particular id
}
}
}
}
}
}
```
# Implementation of Header View where back and next button has implemented
```swift
struct TabNavigationBar: View {
@Binding var currentIndex: Int
let pageCount: Int
var body: some View {
HStack {
if currentIndex != 0 {
Button {
if currentIndex > 0 {
currentIndex -= 1
}
} label: {
Text("back")
}
}
Spacer()
if currentIndex != pageCount - 1 {
Button {
if currentIndex < pageCount {
currentIndex += 1
}
} label: {
Text("next")
}
}
}
}
}
```
I tried Asperis's solution, but I still couldn't disable the swiping, and adding disabled to true didn't work since I want the child views to be interactive. The solution that worked for me was using Majid's (https://swiftwithmajid.com/2019/12/25/building-pager-view-in-swiftui/) custom Pager View and adding a conditional like Asperi's solution.
Majid's PagerView with conditional:
```
import SwiftUI
struct PagerView<Content: View>: View {
let pageCount: Int
@Binding var canDrag: Bool
@Binding var currentIndex: Int
let content: Content
init(pageCount: Int, canDrag: Binding<Bool>, currentIndex: Binding<Int>, @ViewBuilder content: () -> Content) {
self.pageCount = pageCount
self._canDrag = canDrag
self._currentIndex = currentIndex
self.content = content()
}
@GestureState private var translation: CGFloat = 0
var body: some View {
GeometryReader { geometry in
HStack(spacing: 0) {
self.content.frame(width: geometry.size.width)
}
.frame(width: geometry.size.width, alignment: .leading)
.offset(x: -CGFloat(self.currentIndex) * geometry.size.width)
.offset(x: self.translation)
.animation(.interactiveSpring(), value: currentIndex)
.animation(.interactiveSpring(), value: translation)
.gesture(!canDrag ? nil : // <- here
DragGesture()
.updating(self.$translation) { value, state, _ in
state = value.translation.width
}
.onEnded { value in
let offset = value.translation.width / geometry.size.width
let newIndex = (CGFloat(self.currentIndex) - offset).rounded()
self.currentIndex = min(max(Int(newIndex), 0), self.pageCount - 1)
}
)
}
}
}
```
ContentView:
```
import SwiftUI
struct ContentView: View {
@State private var currentPage = 0
@State var canDrag: Bool = true
var body: some View {
PagerView(pageCount: 3, canDrag: $canDrag, currentIndex: $currentPage) {
VStack {
Color.blue
Button {
canDrag.toggle()
} label: {
Text("Toogle drag")
}
}
VStack {
Color.red
Button {
canDrag.toggle()
} label: {
Text("Toogle drag")
}
}
VStack {
Color.green
Button {
canDrag.toggle()
} label: {
Text("Toogle drag")
}
}
}
}
}
```