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

Swiper Image Disappears on IOS when Icon Pressed #836

Open
chetanparakh opened this issue Jul 24, 2018 · 3 comments
Open

Swiper Image Disappears on IOS when Icon Pressed #836

chetanparakh opened this issue Jul 24, 2018 · 3 comments

Comments

@chetanparakh
Copy link

chetanparakh commented Jul 24, 2018

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

@adammcarth
Copy link

+1 I have this bug as well. Bizarre.

@chawlatushar5
Copy link

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

@adammcarth
Copy link

adammcarth commented Aug 12, 2018

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 🤞

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

3 participants