react-native-pager-view icon indicating copy to clipboard operation
react-native-pager-view copied to clipboard

How to make ViewPager be more aggressive in responding to horizontal gesture when nested inside a vertical ScrollView?

Open zholmes1 opened this issue 3 years ago • 13 comments

Hi everyone,

Users are reporting that it is difficult to use the ViewPager to successfully scroll left and right between images, since the ScrollView that the ViewPager is nested in seems to grab the event more than it should.

Example

Indeed, I compared my app to Google Maps which has a very similar UI: A horizontally scrollable set of images inside a vertically scrolling parent view. In Google Maps, I can move my finger at 45 degrees to either side, and the horizontal images view takes the event. In my app, moving my finger 45 degrees is picked up by the ScrollView and the entire page begins scrolling up and down.

Here, the purple arrows are what is handled by both apps successfully. The blue arrows are what is handled successfully by Google Maps but not by ScrollView/ViewPager. In Google Maps, the result is a horizontal scroll, in my app the result is a vertical scroll - and angry users.

I have looked into the props and found: ViewPager.onStartShouldSetResponder and ViewPager.onMoveShouldSetResponderCapture. I tried providing a function that always returns true for both, but got no effect in my app. I also tried the same props but returning false for the ScrollView. Still nothing. I also tried ScrollView.disableScrollViewPanResponder, although I'm not really sure what this does.

Somewhat at a loss here, can anyone help?

zholmes1 avatar Sep 21 '21 05:09 zholmes1

Hey 👋 Could you provide a code snippet ? Could you take a look at this code example: https://github.com/callstack/react-native-pager-view/blob/master/example/src/ScrollablePagerViewExample.tsx ? it seems to be the same

troZee avatar Sep 21 '21 11:09 troZee

Hey @troZee! Thanks so much for the quick reply.

I ran the example app and checked out ScrollablePagerViewExample. You're correct, this is the exact same UI that I have. However, the example suffers from the same experience. A slightly off-horizontal swipe on a ViewPager will be picked up by the vertical ScrollView container. I encourage you to open that example and swipe around a bit. I think eventually you will encounter a time where you are wanting to swipe left or right but end up with a scroll up or down instead.

In contract, check out the Google Maps app for what I think is a better user experience. (at least in Android, I can't confirm for iOS) A slightly off-horizontal swipe on the place images will not be picked up by the parent vertical scrolling view. In my example picture in my opening message, the blue arrows are what I'm referring to. GMaps picks that up as a horizontal gesture, ViewPager/ScrollView picks it up as a vertical gesture. React Native's Gesture Responder System looks to play a part in the solution.

If we can get this solved I'll be happy to write up some documentation on it for you. I think this is a fairly common type of UI. Alternatively, it could also be something that simply gets written directly into the ViewPager library. (i.e. ViewPager always picks up gestures up to a certain angle)

zholmes1 avatar Sep 21 '21 13:09 zholmes1

Also looking for a solution to this issue. Having a ViewPager inside a ScrollView is tricky to use on Android. Fine on iOS though.

dcoulter45 avatar Sep 29 '21 10:09 dcoulter45

@dcoulter45 I stopped using ViewPager and replaced it with FlatList with pagingEnabled. Works really well honestly and doesn't require an extra native library. And it definitely responds more naturally to gestures when inside a ScrollView

zholmes1 avatar Oct 08 '21 00:10 zholmes1

@zholmes1 are you able to use the flatlist with pagination controls, like a tab component for example?

vbylen avatar Nov 12 '21 20:11 vbylen

Yeah you could definitely do scrollToIndex do manually change the page. And there is definitely also a prop that will help you determine which page(s) are currently visible

zholmes1 avatar Nov 12 '21 20:11 zholmes1

I have a similar issue but with horizontal PagerView, which has pages containing WebViews. When I try to scroll the WebView vertically, it triggers the horizontal scroll in PagerView and sometimes even triggers text selection in the WebView. And it only happens on Android, iOS is working fine.

I searched the issues here and the web for the answer and it seems that many people have the same issue, but I couldn't find the solution.

Using FlatList gives the same effect (

And help is greatly appreciated.

velsa avatar Feb 11 '22 03:02 velsa

We are facing the same issue. Here is a nice article explaining the source of the issue: https://bladecoder.medium.com/fixing-recyclerview-nested-scrolling-in-opposite-direction-f587be5c1a04

There is a workaround which we are using, but it has some drawbacks. We are decreasing the pager swipe sensitivity, however you need to find the sweet spot between fixing this issues and making the swiping too hard.

tothvoj-gl avatar Feb 21 '22 14:02 tothvoj-gl

I have a similar issue but with horizontal PagerView, which has pages containing WebViews. When I try to scroll the WebView vertically, it triggers the horizontal scroll in PagerView and sometimes even triggers text selection in the WebView. And it only happens on Android, iOS is working fine.

I searched the issues here and the web for the answer and it seems that many people have the same issue, but I couldn't find the solution.

Using FlatList gives the same effect (

And help is greatly appreciated.

I already found a solution to avoid the problem:

  • Up-Down-Left-Right gesture conflict when WebView inside PagerView

Detail : https://github.com/callstack/react-native-pager-view/issues/519#issuecomment-1178495661

zhuanghongji avatar Jul 08 '22 03:07 zhuanghongji

velsa

Hi, did you find the soultion? If yes, then please post it here, I'd really appreciate it. Stuck with same problem.

Prakunj avatar Sep 20 '22 13:09 Prakunj

Hi, did you find the soultion? If yes, then please post it here, I'd really appreciate it. Stuck with same problem.

Yep, switched everything to FlatList with pagingEnabled={true}

zholmes1 avatar Sep 20 '22 14:09 zholmes1

Hi, did you find the soultion? If yes, then please post it here, I'd really appreciate it. Stuck with same problem.

Yep, switched everything to FlatList with pagingEnabled={true}

@zholmes1 thanks for replying. I tried but your solution has same effect as @velsa also mentioned above. It is not working. I have webview inside viewpager. Issue is viewpager steals webview's vertical scroll and as a result viewpager scroll horizontally

Prakunj avatar Sep 21 '22 04:09 Prakunj

@Prakunj

Ah okay that's slightly different than the original issue I reported. I can see why FlatList wouldn't help your case. I'm having a hard time imagining a UX of tabbed WebViews so it seems a bit anti-pattern to me. I suppose the only solution would be to have a floating FAB to "unlock" zoom/pan in the WebView and disable pointer events in the TabView/FlatList. So this way the user shows their intent on whether the want to be tabbing or interacting with the WebView.

zholmes1 avatar Sep 21 '22 08:09 zholmes1