React-native-swiper: Swiper Image Disappears on IOS when Icon Pressed

Created on 24 Jul 2018  ·  3Comments  ·  Source: leecade/react-native-swiper

Which OS ?

IOS

Version

Which versions are you using:

  • react-native-swiper v?
    ^1.5.13

  • react-native v0.?.?
    0.53.0

  • react-native-elements v
    ^1.0.0-beta5

Expected behaviour

Image Should Not Disappear when heart icon is clicked
Should be able to swipe images

Actual behaviour

View/ Image nested within disappears on clicking heart icon
Can see pagination style (dot). But it does not move on swiping swiper region (when the images disappeared).

My Code

import React, { Component } from 'react';

import {
    Text,
    View,
    Image,
    Platform
} from 'react-native';

import {
    Icon
} from "react-native-elements";

import styles from 'app/styles/styles.js';
import textStyles from 'app/styles/textStyles.js';

import sett from "app/config/others.js";

import Swiper from 'react-native-swiper';

import {connect} from "react-redux";
import { removeSelectedSavedDeals, saveThisDeal } from "app/actions/savedDealsAction.js";

class ImageSwiper extends Component {
    constructor(props) {
        super(props);
        this.state = {visiableSwiper: false};
    }

    componentDidMount(){
        this.reRenderImageSwiper();
    }

    reRenderImageSwiper=()=>{
        //to fix react-native-swiper in android bug
        if (Platform.OS === 'android' || Platform.OS === 'ios') {
            setTimeout(() => {
                this.setState({ visiableSwiper: true })
            }, 0)
        }
    }

    render(){
        if(this.state.visiableSwiper){
            return(
                <View style={styles.dealDetailImageContainer}>
                    <Swiper
                    width="100%"
                    height='100%'
                    paginationStyle={{bottom: 0}}>
                        <View>
                            <Image
                                source={{uri: 'https://img.grouponcdn.com/deal/5ftJ6ynJzP1uZSzRiroR/1D-2048x1229/v1/t440x300.jpg'}}
                                style={styles.dealDetailImage}/>
                        </View>
                        <View>
                        <Image
                                source={{uri: "https://img.grouponcdn.com/iam/7ACobgMVbvLMwveg34B8/mb-2048x1242/v1/t440x300.jpg"}}
                                style={styles.dealDetailImage}/>
                        </View>
                    </Swiper>
                </View>
            );
        }
        else{
            return (<View></View>)
        }
    }
};

class DealDetailComponent1 extends Component{

    constructor(props) {
        super(props);
        this.state = {
            isSaved: false,
            currentDeal: {}
        }
    }

    checkIfDealIsSaved=()=>{
        var isSaved = this.props.savedDealsListDataSource.some(item => item._id === this.props.navigation.getParam("dealDetails")._id)
        if(isSaved){
            this.setState({
                isSaved: true
            })
        }
        return isSaved;

    }

    componentDidMount(){
        this.checkIfDealIsSaved();
    }

    saveThisDeal = () => {
        console.log("Save This Deal");
        this.props.saveThisDeal(this.props.navigation.getParam("dealDetails"));
        this.setState({
            isSaved:!this.state.isSaved
        })
    }


    removeSavedDeals = () => {
        console.log("Remove This Deal");
        this.props.removeSelectedSavedDeals([this.props.navigation.getParam("dealDetails")._id], this.props.savedDealsListDataSource);
        this.setState({
            isSaved:!this.state.isSaved
        })
    }

    render(){
            return (
                <View>
                    <ImageSwiper/>
                    <View style={styles.dealDetailComponentContainer}>
                        <View style={styles.dealDetailPageBusinessNameAndHeartContainer}>
                            <View>
                                <Text style={textStyles.text1}>Pizza Hut</Text>
                                <Text style={textStyles.text2}>Corona, New York</Text>
                            </View>
                            <View style={styles.dealDetailPageHeartContainer}>
                                <Icon
                                    name={this.state.isSaved ? "heart" : "heart-o"}
                                    type='font-awesome'
                                    color="red"
                                    size={22}
                                    onPress={() => this.state.isSaved ? this.removeSavedDeals() : this.saveThisDeal()}
                                />
                            </View>
                        </View>
                    </View>  
                </View>
            );
    }
}

const mapStateToProps = (state) => {
    return {
        savedDealsListDataSource: state.savedDealsReducer.savedDealsListDataSource
    }
   }

export default connect(mapStateToProps, {removeSelectedSavedDeals, saveThisDeal})(DealDetailComponent1)

screen shot 2018-07-24 at 5 56 54 pm

After Clicking on the Heart Icon

screen shot 2018-07-24 at 5 57 06 pm

Most helpful comment

+1 I have this bug as well. Bizarre.

All 3 comments

+1 I have this bug as well. Bizarre.

Can't seem to find any workarounds for it. Please resolve ASAP.

Just a heads up to anyone else with this problem, we made the ultimate decision that react-native-swiper was too unstable to be viable for production. Our work-around uses a package called react-native-snap-carousel, which can be easily extended to mimic the functionality of this library.

The ONLY drawback is that you need to specify the exact width of the screen or container, but if that's not a deal breaker - checkout an example of how the above application would work:

import React, { Component } from 'react';
import { View, StyleSheet, Dimensions } from 'react-native';
import SnapCarousel from 'react-native-snap-carousel';

export default class ImageSwiper extends Component {
  constructor(props) {
    super(props);
    this.screenWidth = Dimensions.get('window').width;
    this.state = {
      imageUrls: ['http://img1.png', 'http://img2.png', 'http://img3.png'],
      currentSlideIndex: 0,
    };
    this._updateCurrentSlideIndex = this._updateCurrentSlideIndex.bind(this);
  }

  // Should be a static function since we don't use `this` inside.
  static renderSlide(imageUrl) {
    return <Image source={{ uri: imageUrl }} width={this.screenWidth} height={250} />;
  }

  _updateCurrentSlideIndex(i) {
    this.setState({ currentSlideIndex: i });
  }

  render() {
    return (
      <View style={s.container}>
        {/* Slider */}
        <SnapCarousel
          data={this.state.imageUrls}
          renderItem={ImageSwiper.renderSlide}
          layout="default"
          sliderWidth={this.screenWidth} // cannot be a percentage
          itemWidth={this.screenWidth} // cannot be a percentage
          inactiveSlideScale={1} // neutralise carousel effect
          inactiveSlideOpacity={1} // neutralise carousel effect
          onSnapToItem={i => this._updateCurrentSlideIndex(i)} // update slide dots
        />

        {/* Slide Dots */}
        <View style={s.dotsContainer}>
          {this.state.imageUrls.map((url, i) => (
            <View
              key={`dot_${url}`}
              style={[
                s.dot,
                i === this.state.currentSlideIndex ? s.dotCurrent : {},
              ]}
            />
          ))}
        </View>
      </View>
    );
  }
}

// Styles
const s = StyleSheet.create({
  container: {
    width: '100%',
  },

  dotsContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 10,
  },

  dot: {
    width: 8,
    height: 8,
    borderRadius: 4,
    marginRight: 5,
    backgroundColor: '#CCCCCC',
  },

  dotCurrent: {
    backgroundColor: '#007AFF',
  },
});

Although it needs a little more customisation to get going, Snap Carousel is much better maintained and has documented features that actually work. You also get the major performance boost of a FlatList to render slides - so I hoped this at least helped someone.

But yeah, if it's too late to switch packages, hopefully you get a bug fix soon 🤞

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tibic picture tibic  ·  3Comments

losikov picture losikov  ·  3Comments

kylehagler picture kylehagler  ·  3Comments

nicolabortignon picture nicolabortignon  ·  3Comments

itinance picture itinance  ·  3Comments