ascoders / react-native-image-zoom

react native image pan and zoom
MIT License
639 stars 282 forks source link

Prevent FlatList scrolling while image zoomed #42

Open Stmol opened 6 years ago

Stmol commented 6 years ago

Hi! I have a FlatList with items wrapped to ImageZoom:

<FlatList
     horizontal
     pagingEnabled={true}
     showsHorizontalScrollIndicator={false}

     data={this.props.images}
     renderItem={item => this.renderImage(item)}
/>

And the render image function is:

renderImage = ({item}) => {
    return (
      <View style={{width: SCREEN_WIDTH, height: 'auto'}}>
        <ImageZoom
          cropWidth={Dimensions.get('window').width}
          cropHeight={Dimensions.get('window').height}
          imageWidth={Dimensions.get('window').width}
          imageHeight={'100%'}
        >
          <FastImage
            resizeMode={FastImage.resizeMode.contain}
            source={{uri: item.source.uri, cache: 'force-cache'}}
          />
        </ImageZoom>
      </View>
    )
  }

But as I starting zoom an image, the FlatList trying to scroll to next (or previous) page. How to prevent the FlatList responding to gestures while Image are zooming?

hardcodet commented 6 years ago

@Stmol Are you seeing this on Android too? I have the reverse issue on Android: When using this control in a carousel, the carousel doesn't scroll anymore because the zoom control takes all the gestures.

ashrithks commented 6 years ago

https://www.npmjs.com/package/react-native-image-gallery

ios-dev-newbie commented 6 years ago

I am facing the same issue in android. My scrolling view stops scrolling. ImageZoom took charge of scrolling. Can we still achieve scrolling with zoom in app.?

Please let me know.

littlehome-eugene commented 6 years ago

same here,

https://github.com/ascoders/react-native-image-viewer/blob/master/src/image-viewer.component.tsx uses this library and doesn't seem to have the problem..

ascoders commented 6 years ago

@littlehome-eugene great, are there any other questions?

littlehome-eugene commented 6 years ago

Well but the library I mentioned doesn't use flatlist, I'd like to know if it's possible to use flatlist as a wrapper as OP asked

ascoders commented 6 years ago

I'm not tried yet, but it's seem possible to replace Animated.View with FlatList in react-native-image-zoom-viewer, welcome pr!

littlehome-eugene commented 6 years ago

Yeah seems possible, but doesn't work, ImageZoom took charge of scrolling. as @stmol and @ios-dev-newbie has reported.

littlehome-eugene commented 6 years ago

There's a lengthy discussion on this topic..

https://github.com/archriss/react-native-snap-carousel/issues/264

hanishcodebrew commented 6 years ago

I am also facing the same issue mentioned by @ios-dev-newbie ? Please help

Dror-Bar commented 5 years ago

My solution:

const [scroll, setScroll] = useState(true);

<Flatlist
    ...
    scrollEnabled={scroll}
    renderItem={({ item }) =>
          <ImageZoom
                   ...
                   panToMove={!scroll}
                   onMove={({ scale }) => { setScroll(scale === 1 ? true : false) }}
                   <Image
                   ...
                   />
           </ImageZoom>}
/>
darron1217 commented 3 years ago

The solution above not worked well on Android.

So I upgraded ImageZoom into the code below.

And it works well now.

const ImageViewer: FC<ImageViewerProps> = ({
  source,
  width = Dimensions.get('window').width,
  height = Dimensions.get('window').height,
  onMove,
  ...props
}) => {
  const scaleValue = useRef(1);
  return (
    <ImageZoom
      cropWidth={Dimensions.get('window').width}
      cropHeight={Dimensions.get('window').height}
      imageWidth={width}
      imageHeight={height}
      minScale={1}
      {...props}
      onStartShouldSetPanResponder={(e) => {
        return e.nativeEvent.touches.length === 2 || scaleValue.current > 1;
      }}
      onMove={({scale}) => {
        scaleValue.current = scale;
        onMove && onMove({scale});
      }}>
      <View
        style={{width: '100%', height: '100%'}}
        onStartShouldSetResponder={(e) => {
          return e.nativeEvent.touches.length < 2 && scaleValue.current <= 1;
        }}>
        <Image
          source={source}
          resizeMode="contain"
          style={{width: '100%', height: '100%'}}
        />
      </View>
    </ImageZoom>
  );
};
DonOzOn commented 3 years ago
const ImageViewer: FC<ImageViewerProps> = ({
  source,
  width = Dimensions.get('window').width,
  height = Dimensions.get('window').height,
  onMove,
  ...props
}) => {
  const scaleValue = useRef(1);
  return (
    <ImageZoom
      cropWidth={Dimensions.get('window').width}
      cropHeight={Dimensions.get('window').height}
      imageWidth={width}
      imageHeight={height}
      minScale={1}
      {...props}
      onStartShouldSetPanResponder={(e) => {
        return e.nativeEvent.touches.length === 2 || scaleValue.current > 1;
      }}
      onMove={({scale}) => {
        scaleValue.current = scale;
        onMove && onMove({scale});
      }}>
      <View
        style={{width: '100%', height: '100%'}}
        onStartShouldSetResponder={(e) => {
          console.log(
            scaleValue.current,
            e.nativeEvent.touches.length < 2 && scaleValue.current <= 1,
          );
          return e.nativeEvent.touches.length < 2 && scaleValue.current <= 1;
        }}>
        <Image
          source={source}
          resizeMode="contain"
          style={{width: '100%', height: '100%'}}
        />
      </View>
    </ImageZoom>
  );
};

Thanks a lot , it worked 👍

Quang-Dong commented 3 years ago

The solution above not worked well on Android.

So I upgraded ImageZoom into the code below.

And it works well now.

const ImageViewer: FC<ImageViewerProps> = ({
  source,
  width = Dimensions.get('window').width,
  height = Dimensions.get('window').height,
  onMove,
  ...props
}) => {
  const scaleValue = useRef(1);
  return (
    <ImageZoom
      cropWidth={Dimensions.get('window').width}
      cropHeight={Dimensions.get('window').height}
      imageWidth={width}
      imageHeight={height}
      minScale={1}
      {...props}
      onStartShouldSetPanResponder={(e) => {
        return e.nativeEvent.touches.length === 2 || scaleValue.current > 1;
      }}
      onMove={({scale}) => {
        scaleValue.current = scale;
        onMove && onMove({scale});
      }}>
      <View
        style={{width: '100%', height: '100%'}}
        onStartShouldSetResponder={(e) => {
          console.log(
            scaleValue.current,
            e.nativeEvent.touches.length < 2 && scaleValue.current <= 1,
          );
          return e.nativeEvent.touches.length < 2 && scaleValue.current <= 1;
        }}>
        <Image
          source={source}
          resizeMode="contain"
          style={{width: '100%', height: '100%'}}
        />
      </View>
    </ImageZoom>
  );
};

You save my life, thank you so much!!!!!

castalonirenz commented 3 years ago

The solution above not worked well on Android.

So I upgraded ImageZoom into the code below.

And it works well now.

const ImageViewer: FC<ImageViewerProps> = ({
  source,
  width = Dimensions.get('window').width,
  height = Dimensions.get('window').height,
  onMove,
  ...props
}) => {
  const scaleValue = useRef(1);
  return (
    <ImageZoom
      cropWidth={Dimensions.get('window').width}
      cropHeight={Dimensions.get('window').height}
      imageWidth={width}
      imageHeight={height}
      minScale={1}
      {...props}
      onStartShouldSetPanResponder={(e) => {
        return e.nativeEvent.touches.length === 2 || scaleValue.current > 1;
      }}
      onMove={({scale}) => {
        scaleValue.current = scale;
        onMove && onMove({scale});
      }}>
      <View
        style={{width: '100%', height: '100%'}}
        onStartShouldSetResponder={(e) => {
          return e.nativeEvent.touches.length < 2 && scaleValue.current <= 1;
        }}>
        <Image
          source={source}
          resizeMode="contain"
          style={{width: '100%', height: '100%'}}
        />
      </View>
    </ImageZoom>
  );
};

Thanks for this! Appreciate it!