react-native-image-viewer
react-native-image-viewer copied to clipboard
renderHeader messing up with renderFooter
I noticed that if I use renderHeader
and renderFooter
together, my footer needs to add the exact height of the header otherwise it will be behind the screen on the bottom. If the height in my header is 50 so with a height of 70 of my footer it's seen as 20 pixels.
_renderHeader = (currentIndex: number, pics: IImageInfo[]) => {
return (
<View style={{ height: 50, backgroundColor: 'transparent' }}>
<Text style={{ color: 'white' }}>{`${currentIndex + 1}/${
pics.length
}`}</Text>
</View>
);
};
_renderFooter(currentIndex: number) {
return (
<View style={{ height: 70, backgroundColor: 'red' }}> //i see only 20 pixels here since header is 50
<Text style={{ fontSize: 16, color: 'white', textAlign: 'center' }}>
{currentIndex + 1}
</Text>
</View>
);
}
If I understand correctly, the header is not absolute positioned as a footer. Therefore, the header pushes down the image area, making the footer disappear.
In my case, I also force the absolute position in the header and both appear:
const Lightbox = ({ images, selected, onCloseLightbox }: Props) => {
const renderHeader = () => (
<View style={styles.header}>
<Text style={{ color: '#fff' }}>Header</Text>
</View>
)
const renderFooter = (index: number) => (
<Text style={styles.footerText}>{index + 1} / {images.length}</Text>
)
return (
<Modal
transparent={true}
animationType="fade"
visible={typeof selected !== 'undefined'}
onRequestClose={onCloseLightbox}
>
<ImageViewer
imageUrls={images}
index={selected}
enableSwipeDown
onSwipeDown={onCloseLightbox}
renderHeader={renderHeader}
renderFooter={renderFooter}
footerContainerStyle={styles.footer}
renderIndicator={() => <React.Fragment />}
/>
</Modal>
);
}
const styles = StyleSheet.create({
header: {
position: 'absolute',
top: 0,
left: 0,
backgroundColor: '#000',
width: '100%',
zIndex: 9999
},
footer: {
width: '100%',
backgroundColor: '#000'
},
footerText: {
color: '#fff',
textAlign: 'center',
margin: 10
}
})
I will try do as in your example. Was thinking that's a bug, thanks .
My solution was incomplete. Its work when has no problem that header and footer can overlap the image (but isn't my case).
To exemplify, here is a print when image is vertically and hide behind header and footer:

The solution is place header before the <ImageViewer>
and footer after. This way, the view with the image gonna calculate the height considering the spacing between header and footer:
const Lightbox = ({ images, selected, onCloseLightbox }: Props) => {
const [index, setIndex] = useState<number>()
const insets = useSafeAreaInsets();
const renderHeader = () => (
<View
style={[
styles.header,
Platform.OS === 'ios' ? { paddingTop: insets.top } : { }
]}
>
<MaterialIcons
name='close'
style={styles.close}
onPress={onCloseLightbox}
/>
</View>
)
const renderFooter = () => (
<View style={[
styles.footer,
Platform.OS === 'ios' ? { paddingBottom: insets.bottom } : { }
]}>
<CustomText
weight='600'
style={styles.footerText}
>{index || 1} / {images.length}</CustomText>
</View>
)
return (
<Modal
transparent
animationType="fade"
visible={typeof selected !== 'undefined'}
onRequestClose={onCloseLightbox}
>
{renderHeader()}
<ImageViewer
imageUrls={images}
index={selected}
enableSwipeDown
enablePreload
onSwipeDown={onCloseLightbox}
renderIndicator={(index?: number) => {
setIndex(index)
return <React.Fragment />
}}
useNativeDriver
/>
{renderFooter()}
</Modal>
);
}
const styles = StyleSheet.create({
header: {
backgroundColor: '#000',
width: '100%',
zIndex: 9999
},
close: {
alignSelf: 'flex-end',
color: '#fff',
fontSize: 30,
margin: 10
},
footer: {
width: '100%',
backgroundColor: '#000'
},
footerText: {
color: '#fff',
textAlign: 'center',
margin: 10
},
arrow: {
color: '#fff',
fontSize: 40,
elevation: 2,
backgroundColor: 'rgba(0, 0, 0, 0.3)'
}
})
export default Lightbox;