Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollView conflicts with NavigationLink swipe-back gesture

Tags:

ios

swift

swiftui

I have a NavigationLink view that contains a ScrollView that mainly shows a list of contacts. However, the ScrollView sometimes register user's pop gesture as a scrolling gesture, thereby preventing the user swipe back out of the NavigationLink view.

The general structure is like the follow:

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink (destination: AnotherView()) {Text("enter")}
        }
    }
}

struct AnotherView: View {
    var body: some View {
        ScrollView {
            LazyVStack(alignment: .leading) {
             // ... a list of things
            }
        }
    }
}

Is there anyway to tell ScrollView to ignore the horizontal-ish drag gestures so that NavigationLink can be swiped out properly and smoothly?

like image 950
PipEvangelist Avatar asked Oct 13 '25 10:10

PipEvangelist


2 Answers

I had a similar problem with TabView. The following extension solved it:

extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
    super.viewDidLoad()
    interactivePopGestureRecognizer?.delegate = self
}

// Allows swipe back gesture after hiding standard navigation bar with .navigationBarHidden(true).
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    viewControllers.count > 1
}

// Allows interactivePopGestureRecognizer to work simultaneously with other gestures. 
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    viewControllers.count > 1
}

// Blocks other gestures when interactivePopGestureRecognizer begins (my TabView scrolled together with screen swiping back)
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    viewControllers.count > 1
}
}

Hope this will be helpful.

like image 120
IronHead Avatar answered Oct 15 '25 02:10

IronHead


I made it work by attaching .gesture(DragGesture(minimumDistance: 20)) to my ScrollView so that the pop gesture of NavigationView has a higher priority over ScrollView's gesture.

like image 39
PipEvangelist Avatar answered Oct 15 '25 04:10

PipEvangelist