I have a image carousel underneath a vertical ScrollView. I want to be able to slide some content on top of my image carousel. You can see in the current way I am implementing it there is an issue. I can no longer interact with my image carousel.
I would like to be able to scroll content on top of my carousel, but when there is not content on top, I would like to be able to use my carousel like normal. If possible, I would also like to be able for the scrolling to not bounce back to where it started, but to stay where it is left. If I scroll my content to the top of the screen, it needs to stay at the top of the screen.
I have attached some code as to how I am rendering the scrollView and the carousel but every line of code can be found on my snack example here. It reproduces my issue exactly.
export default function App() {
return (
<View style={{backgroundColor: '#d1cfcf', flex: 1}}>
<View style={{position: 'absolute',}}>
<Carousel/>
</View>
{/* beginning of white box below image*/}
<ScrollView style={{height: scale(500)}}>
<View style={styles.whiteBox}>
<View style={{flexDirection: 'row', top: scale(15), left: scale(20)}}></View>
{/* grey body in white text box*/}
<View style={styles.greyBody}></View>
</View>
{/* end of white box below image*/}
{/* grey body in white text box*/}
{/* beginning of description*/}
<View style={{bottom: scale(340),left: scale(25), position: "absolute", backgroundColor: 'red'}}>
<Text style={{fontSize: 15, color: 'black', fontWeight: 'bold'}}>
Description
</Text>
</View>
{/* beginning of View more text*/}
<View style={{position: 'absolute', top: scale(400), left: scale(25), height: scale(100), width: scale(300),}}>
<Text>
Lorem ipsum dolor sit amet, in quo dolorum ponderum, nam veri molestie constituto eu. Eum enim tantas sadipscing ne, ut omnes malorum nostrum cum. Errem populo qui ne, ea ipsum antiopam definitionem eos. Lorem ipsum dolor sit amet,
</Text>
</View>
</ScrollView>
{/* End of View more text*/}
{/* End of description*/}
</View>
);
}
You are using absolute positioning for both of your views, that is an absolute position for Carousel
and the ScrollView
below it. We can debug the issue by adding a zIndex: 2
to the ScrollView
in App
and set backgroundColor: "red"
which enables us to see the issue here:
ScrollView
in App
is in fact on top of the Carousel
.This might be intended since we want to scroll "over" the Carousel
. However, it disables the ability to touch
, e.g. scroll, the Carousel
.
This can be easily fixed by changing the following:
{height: scale(500)}
of the ScrollView
in App
,{marginTop: 250, overflow: "visible"}
to the ScrollView
in App
.The top margin removes the part which is actually on top
of the Carousel
and the overflow: "visible"
still allows us to scroll the ScrollView
in App
over the Carousel
while scrolling the Carousel
works now.
Notice that the text has shifted to the bottom now. We can fix this by
top: scale(400)
of the view that contains your text to top: scale(200)
.I have made a fully working snack using your initial code. Notice that I have only tested this on iOS. Android might behave differently.
Since I have only changed App.js
, here is the updated code of App.js
which fixes the issue.
import React,{useState} from 'react';
import { Text, View, StyleSheet, ScrollView, } from 'react-native';
import Carousel from './Carousel';
import {
scale,
verticalScale,
moderateScale,
ScaledSheet,
} from 'react-native-size-matters';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import ViewMoreText from 'react-native-view-more-text';
export default function App() {
return (
<View style={{backgroundColor: '#d1cfcf', flex: 1}}>
<View style={{position: 'absolute',}}>
<Carousel/>
</View>
{/* beginning of white box below image*/}
<ScrollView style={{marginTop: 250, overflow: "visible"}}>
<View style={styles.whiteBox}>
<View style={{flexDirection: 'row', left: scale(20)}}></View>
{/* grey body in white text box*/}
<View style={styles.greyBody}></View>
</View>
{/* end of white box below image*/}
{/* grey body in white text box*/}
{/* beginning of description*/}
<View style={{bottom: scale(340),left: scale(25), position: "absolute", backgroundColor: 'red'}}>
<Text style={{fontSize: 15, color: 'black', fontWeight: 'bold'}}>
Description
</Text>
</View>
{/* beginning of View more text*/}
<View style={{position: 'absolute', top: scale(200), left: scale(25), height: scale(100), width: scale(300),}}>
<Text>
Lorem ipsum dolor sit amet, in quo dolorum ponderum, nam veri molestie constituto eu. Eum enim tantas sadipscing ne, ut omnes malorum nostrum cum. Errem populo qui ne, ea ipsum antiopam definitionem eos. Lorem ipsum dolor sit amet,
</Text>
</View>
</ScrollView>
{/* End of View more text*/}
{/* End of description*/}
</View>
);
}
const styles = StyleSheet.create({
whiteBox: {
height: scale(175),
width: scale(300),
backgroundColor: 'white',
borderRadius: 10,
position: 'absolute',
left: scale(25),
},
distanceBox: {
height: scale(30),
width: scale(80),
backgroundColor: 'white',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
position: 'absolute',
top: scale(190),
left: scale(45),
justifyContent: 'center',
flexDirection: 'row'
},
busyView:{
height: scale(20),
width: scale(40),
backgroundColor: '#ffe6f3',
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
},
pinkBubble: {
height: scale(20),
width: scale(40),
backgroundColor: '#ffe6f3',
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
},
greyBody: {
backgroundColor: '#d1cfcf',
width: scale(255),
height: scale(75),
alignSelf: 'center',
borderRadius: 15,
top: scale(70)
}
});