if I press Android HardwareHomeKey let the app back Backstage then open my app, swiper lost sliding effect。
My code:
'use strict';
import React, {
Component
} from 'react';
import {
View,
Text,
Dimensions,
Image,
TouchableOpacity,
Modal,
StyleSheet,
} from 'react-native';
const {
width,
height
} = Dimensions.get('window');
const imageSource = [
require('../images/guide_page1.png'),
require('../images/guide_page2.png'),
require('../images/guide_page3.png'),
require('../images/guide_page4.png'),
];
import { RatiocalWidth, RatiocalHeight, RatiocalFontSize } from '../style';
import { toastShort } from './ToastUtil';
import Swiper from 'react-native-swiper';
export default class WelcomePage extends Component {
constructor(props) {
super(props);
this.state = {
isShowCircleDot: true,
}
this._renderImg = this._renderImg.bind(this);
}
_renderImg() {
const { _click } = this.props
let imageSource = [
require('../images/guide_page1.png'),
require('../images/guide_page2.png'),
require('../images/guide_page3.png'),
require('../images/guide_page4.png'),
];
var imageViews = [];
for (var i = 0; i < imageSource.length; i++) {
if (i == imageSource.length - 1) {
imageViews.push(
<Image
key={i}
style={styles.swiperImage}
source={imageSource[i]} >
<TouchableOpacity style={styles.btnEsperience} onPress={() => _click()} >
<Text style={styles.btnText}>
马上体验
</Text>
</TouchableOpacity>
</Image>
);
}
else {
imageViews.push(
<Image
key={i}
style={styles.swiperImage}
source={imageSource[i]}
/>
);
}
}
return imageViews
}
_renderImage(val, i) {
const { _click } = this.props
return (
<View key={i} style={{ flex: 1, flexDirection: 'column' }}>
<Image
style={styles.swiperImage}
source={imageSource[i]} >
{
i === imageSource.length - 1 ?
<TouchableOpacity style={styles.btnEsperience} onPress={() => _click()} >
<Text style={styles.btnText}>
马上体验
</Text>
</TouchableOpacity>
:
null
}
</Image>
</View>
);
}
_onMomentumScrollEnd(e, state, context) {
if (state.index == 3) {
this.setState({
isShowCircleDot: false,
})
}else {
this.setState({
isShowCircleDot: true,
})
}
}
render() {
const { visible } = this.props
return (
<Modal
animationType={'fade'}
visible={visible}
transparent
onRequestClose={(state) => { } } >
<View style={styles.backgroudView}>
<Swiper
loop={false}
autoplay={false}
showsButtons={false}
showsPagination={false}
width={width}
height={height}
index={0}
onMomentumScrollEnd={(e, state, context) => this._onMomentumScrollEnd(e, state, context)}>
{
imageSource.map((val, i) => this._renderImage(val, i))
}
</Swiper>
</View>
</Modal >
);
}
}
const styles = StyleSheet.create({
backgroudView: {
flexGrow: 1,
backgroundColor: '#ffffff',
},
swiperImage: {
width: width,
height: height,
/**
* contain 根据图片本身的宽高比
* cover,
* stretch
*/
resizeMode: Image.resizeMode.stretch,
justifyContent: 'flex-end',
},
btnEsperience: {
marginBottom: RatiocalHeight(160),
width: width / 2,
height: RatiocalHeight(100),
borderColor: '#1D9FF9',
borderRadius: 7,
borderWidth: 1,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
},
btnText: {
fontSize: RatiocalFontSize(36),
textAlign: 'center',
color: '#1D9FF9',
},
});
I had the same problem, and do:
1.Set a state param like this.state = { loadSwiper = false }
2.When componentDidMount, put this.setState({loadSwiper = true})
3.At the render method, {loadSwiper?
In summary, you just re-render the Swiper after componentDidMount
@WhiteClouds2009 works for me, thanks
you can call Swiper after Modal is shown
I had to add a delay to get mine to work, but yes @WhiteClouds2009 it works!
constructor(props) {
super(props);
this.state = { showSwiper: false };
}
componentDidMount() {
// Must use this 100-ms delayed swiper workaround to render on Android properly
setTimeout(() => {
this.setState({showSwiper: true});
}, 100);
}
render() {
var exampleSwiper = (
<Swiper activeDotColor={'white'} loop={false} >
<View style={{width: 100, height: 100, backgroundColor: 'white'}} />
<View style={{width: 100, height: 100, backgroundColor: 'white'}} />
<View style={{width: 100, height: 100, backgroundColor: 'white'}} />
</Swiper>
);
return (
<Modal presentationStyle={'overFullScreen'}>
{this.state.showSwiper ? exampleSwiper : null}
</Modal>
);
}
Even with this workaround, the issue is still happening. Even tried large delay like 2 seconds.
Does this still have no solution?
+1
someone please have a look at this
+1
I have this problem when changing the underlying data and popping back to a screen (using react-native-navigator) which contains the Swiper. On the first load if works as expected, but later it doesn't.
Does anyone happen to know what is then root cause , so we can figure out a solution other than workarounds for this problem ?
I think I may have solved this particular problem. I stared with the above 'setTimeOut' solution, then saw that Modal has an event called onShow that is called when the modal has finished it's animation, as such the following seems to work or me:
setSwiperVisible(visible){
this.setState({showSwiper: visible});
}
render(){
return(
<Modal
visible={this.state.modalVisible}
onShow={() => {
this.setSwiperVisible(true)
}}
>
{this.state.showSwiper &&
<Swiper>
...
</Swiper>
}
</Modal>
)
}
Now there's no dependence on timers being right! Let me know if it works for you to.
EDIT
Scratch that, only works on the first showing :(
As suggested by @alangumer, this PR solved the problem for me: #761
Hi, is there any update regarding this issue?
Is there any idea why it needs some time delay to show the swiper _again_? I mean, is it like the rendering part that took so slow or anything else?
Most helpful comment
I had to add a delay to get mine to work, but yes @WhiteClouds2009 it works!