10

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.

2
  • Hi, did you manage to get it to work? would you please share the code on github? I am new to react-native thus I cannot comprehend from the answer... thanks a lot.. Commented Nov 7, 2017 at 13:36
  • Hi! I ended up giving up the way I was trying to do and I've done something different, and the images does not zoom. I ended up using the swiper to view the images, and once I click one of them it opens that image in another screen, in a carousel (github.com/archriss/react-native-snap-carousel), which I can swipe through all of them too.
    – waze
    Commented Nov 7, 2017 at 16:04

2 Answers 2

12

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
}
9
  • I tried that, and when I click the image in the swiper, it simply does nothing.. Do you have any code you can share?
    – waze
    Commented May 30, 2017 at 16:42
  • It won't work for images fetched from an API... It works just fine with other images, like the example on their GitHub. This is not working: <ImageViewer imageUrls={{ uri: 'URL/${item.Ficheiro}' }} index={this.state.currentImageIndex}/>
    – waze
    Commented May 31, 2017 at 9:02
  • According to their documentation it should be an array of objects with url as a must have attribute. So it's <ImageViewer imageUrls={[{url: "lala"},{url: "lala"},{url: "lala"}]} />
    – kdenz
    Commented May 31, 2017 at 9:16
  • I can't have an array like that, as I don't know how many photos it comes from the API. Thats why I need to use URL/${item.Ficheiro}. Thats how it works with the swiper. Swiper runs the URL multiple times, as long that is data on item.Ficheiro, and shows all the images.
    – waze
    Commented May 31, 2017 at 9:21
  • Yes but you'll need to find a way to map that data into an array of url objects then. For example declare a constant within render function: const imageUrls = this.state.imagens.map((item,index)=>{ return {url: item.url}} and then <ImageViewer imageUrls={imageUrls} />
    – kdenz
    Commented May 31, 2017 at 9:28
0

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.