Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent scroll on parent view unless edge is met #16

Open
FMCorz opened this issue Jun 5, 2016 · 2 comments
Open

Prevent scroll on parent view unless edge is met #16

FMCorz opened this issue Jun 5, 2016 · 2 comments

Comments

@FMCorz
Copy link
Contributor

FMCorz commented Jun 5, 2016

Hi,

I am trying to use react-native-image-zoom within react-native-viewpager but it does not behave exactly the way I would like it to. I am creating this issue out of desperation as I have not found any solution. I am happy to provide a pull request if I am told how to fix this.

The problem I am facing is that a zoom/drag of the image will not capture the touch event, thus causing the viewpager to drag/switch the pages. In the viewpager the panResponder only captures the event if the pager is not locked, in transition, or if the touch direction is vertical. So, I thought that it was easy enough to just lock the pager while the image was being dragged, but that's not that simple. image-zoom does not trigger any event when the image is dragged, only when it is zoomed. Also the onScaleChange event does not report the current scale but some sort of computed scale, making it hard to detect if the image is current being zoomed in.

I patched (will submit a pull request later) the plugin to report when the Matrix changed, hoping that I could use this to determine whether the pager should be allowed to change page, but I'm confused about the values the photoView::onMatrixChange event reports, the width do not match at all the one reported by onLayout (I got 360 vs 1080), is there something I'm missing here? So this solution ended up being a dead end. Not mentioning that it was super hacky as the scrollView of the viewpager tries to steal the responder. See React 1026.

I also thought I could patch the viewpager, but as it cannot know the current state of image-zoom I figured that it was not a good idea, especially as they already offered the locked option which should be enough.

In short, I would like to disable the view pager (understand bubbling of touch events) when the image has been zoomed in, and we're not on an edge. Basically making photoView::setAllowParentInterceptOnEdge work, it seems that it doesn't because React does not allow native events to be intercepted.

Thanks in advance for your help, guidance, and/or feedback.

@FMCorz
Copy link
Contributor Author

FMCorz commented Jun 6, 2016

I've managed to find a compromise for now, though it required #17 to be integrated. The following prevents the parent viewpager from stealing the gestures when the image is being zoomed in. Though it does not allow the viewpager from regaining the control when the zoom reaches an edge.

class MyComponent extends Component {
  ...
  componentWillMount() {
   this._imgPanResponder = PanResponder.create({
      onStartShouldSetPanResponder: (e, gestureState) => {
        // Set the image as the element that should answer the event.
        if (gestureState.numberActiveTouches == 2) {
          return true;
        }
      },
      onPanResponderTerminationRequest: (e, gestureState) => {
        // Refuse to give the responder to the parent scrollview.
        return false;
      }
    });
  }
  ...
  render() {
    return (
      <ViewPager
        dataSource={this.state.dataSource}
        renderPage={(pageData, pageId, pageIndex) => {
          const source = {uri: pageData.uri};
          return (
            <ImageZoom
              style={styles.image}
              onMatrixChange={(e) => {
                // Lock the ViewPager when the scale is not 1. In order to work
                // nicely this also requires some PanHandlers.
                var isLocked = Math.round(e.nativeEvent.scale * 1000) / 1000 != 1;
                if (isLocked != this.state.isLocked) {
                  this.setState({isLocked: isLocked});
                }
              }}
              {...this._imgPanResponder.panHandlers}
              source={source} />
          );
        }}
        isLoop={false}
        autoPlay={false}
        renderPageIndicator={false}
        locked={this.state.isLocked}
        style={styles.pager} />
    );
  }
...
}

There is still a little quirk where you can drag for a few pixel, then add an extra finger and start zooming in the image while dragging. Though the frame in which this happens in rather small.

@Anthonyzou
Copy link
Owner

I think the native viewpager on android would not have these issues. Of course, there is a bug where pinch and zoom will crash the app. This is an issue from the android and PhotoView side. The fix would be to implement the fix suggested by photoview (Issues With ViewGroups). I haven't had time to test and add this to the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants