callstack / react-native-pager-view

React Native wrapper for the Android ViewPager and iOS UIPageViewController.
MIT License
2.67k stars 411 forks source link

onPageScroll not update position when handle by two touch (IOS) #832

Open jameheller98 opened 3 months ago

jameheller98 commented 3 months ago

Environment

product, develop

Description

When keep scroll by first touch and use another touch to scroll to next page, page is keep position but onPageScroll return props "position" not updated and return to 0

Reproducible Demo

https://github.com/callstack/react-native-pager-view/assets/32564261/842370b2-25ca-4236-8927-0c8f59237ff7

MrRefactor commented 3 months ago

What version of library and react native are you using? Can you reproduce the issue in example app?

jameheller98 commented 3 months ago

react-native-pager-view: 6.3.1 react-native: 0.73.6

I have expo test, you can check here: https://snack.expo.dev/@jameheller98/test-gesture I have another problem is can not use react-native-gesture-handler in PagerView, you can help me something error here! Thank you very much

MrRefactor commented 2 months ago

Please reproduce it on example app, as in the snack you provided you used nested TabView component inside another TabView.

jameheller98 commented 2 months ago

@MrRefactor Okay in problem first I think its small bug and with experiences of user its okay and its only hard with my tester.

NestedScrollableHost.kt

private fun handleInterceptTouchEvent(e: MotionEvent) {
    val orientation = parentViewPager?.orientation ?:  return

    if (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) {
      return
    }

    if (e.action == MotionEvent.ACTION_DOWN && isPreventScrollGesture) {
      initialX = e.x
      initialY = e.y
      parent.requestDisallowInterceptTouchEvent(true)
    } else if (e.action == MotionEvent.ACTION_MOVE && isPreventScrollGesture) {
      val dx = e.x - initialX
      val dy = e.y - initialY
      val isVpHorizontal = orientation == ORIENTATION_HORIZONTAL

      val scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1f
      val scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5f

      if (scaledDx > touchSlop || scaledDy > touchSlop) {
        if (isVpHorizontal == (scaledDy > scaledDx)) {
          // Here is reason 
          parent.requestDisallowInterceptTouchEvent(false)
        } else {
          if (canChildScroll(orientation, if (isVpHorizontal) dx else dy)) {
            parent.requestDisallowInterceptTouchEvent(true)
          } else {
            // Here is reason 
            parent.requestDisallowInterceptTouchEvent(false)
          }
        }
      }
    }
  }

You can check here why when I nested tabview and tabview nested cannot use react-native-gesture-handler