简体   繁体   中英

React-Native image viewer with zoom and swiper

I have an array of images in a Swiper, where I can swipe through them, and when I click in on of them it open on a Modal (using Lightbox). But Lightbox doesn't have Pinch-to-Zoom or swiping.

So im looking for a solution to this. I already have a swiper, but when I open an image, I want to still be able to swipe through all the images (just like Facebook, you can view all the photos, or open one and swipe through them). In addition to this I need to be able to Pinch-to-Zoom.

Right now this is my code:

(Relevant code)

      <Swiper
        styles={{flex: 1}}
        height={250}
        renderPagination={this.renderPagination}
        paginationStyle={{
          bottom: -23, left: null, right: 10
        }} loop={false}>
          {this.state.imagens.map((item, index) => {
            return(
              <NetworkImage
                source={{uri: `URL/${item.Ficheiro}`, height:250, width: Dimensions.get('window').width}}>
                <Lightbox navigator={this.props.navigator}>
                  <Image
                    style={{ height: 300 }}
                    source={{ uri: `URL/${item.Ficheiro}` }}
                  />
                </Lightbox>
              </NetworkImage>
            );
          })}
      </Swiper>

Im using this library for the swiper https://github.com/leecade/react-native-swiper and I saw it has a PhotoView, but I couldn't get it to work.

I've been trying to implement something similar to this as well.

I'm using react-native-image-zoom-viewer for the zoomed in mode after clicking one of the pictures in the swiper. Within the modal, you can zoom in and out an image while swiping between images.

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

I haven't fully implemented the solution yet but it seems you can just wrap the ImageViewer component in any Modal that you can open/close it programmatically.

<Modal visible={this.state.isModalOpened} transparent={true}>
   <ImageViewer imageUrls={images} index={this.state.currentImageIndex}/>
</Modal>

And with the modal somewhere sitting in your page, for the Swiper you can map over your images and return clickable images as follows:

<View style={styles.slide} key={index}>
   <TouchableWithoutFeedback onPress={() => {this.openModal(index)}}>
     <Image
       resizeMode="cover"
       style={styles.image}
       source={{ uri: img.url }}
     />
   </TouchableWithoutFeedback>
</View>

As seen above, each image is wrapped by an onPress that opens the modal according to the image index, so it opens the ImageViewer Modal on the right photo.

And openModal should look something like this:

function openModal(index) {
   this.setState({isModalOpened: true, currentImageIndex: index })
}

And the state should be:

this.state={
  isModalOpened: false,  //Controls if modal is opened or closed
  currentImageIndex: 0   //Controls initial photo to show for modal
}

I'm using react-native-image-zoom-viewer with hooks https://www.npmjs.com/package/react-native-image-zoom-viewer

import React, { useState } from 'react';
import ImageViewer from 'react-native-image-zoom-viewer';

const MultipleImageFeaturePost = ({ route, navigation }) => {
            
     **const { item } = route.params
    const [showModal, setshowModal] = useState(false)
    const [imageIndex, setimageIndex] = useState(0)
    const images = item.post_medias.map(s => ({ url: s.media_name })) **
            
     const renderImages = (item, index) => (
        <TouchableOpacity onPress={() => {
     ** setimageIndex(index)
        setshowModal(true) **
     }}>
            <Image
                source={{ uri: item.media_name }}
                resizeMode='stretch'
                style={{ alignSelf: 'center', height: hp('35'), marginVertical: hp('1%'), width: wp('86%'), borderRadius: 7, backgroundColor: '#A9A9A9' }} />
        </TouchableOpacity>
    )
    return (
        <SafeAreaView style={{ flex: 1, backgroundColor: '#E5EBEE' }}>
            <FlatList
                showsHorizontalScrollIndicator={false}
                data={item.post_medias}
                renderItem={({ item, index }) => renderImages(item, index)}
                keyExtractor={(item) => item.post_media_id + ''}
            />
         
        ** <Modal
            visible={showModal}
            transparent={true}
            onSwipeDown={() => setshowModal(false)}>
            <ImageViewer
                imageUrls={images}
                index={imageIndex}
                onSwipeDown={() => setshowModal(false)}
                // onMove={data => console.log(data)}
                enableSwipeDown={true}/>
        </Modal> **
     </SafeAreaView >
     )
     }

export default MultipleImageFeaturePost

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM