javascriptreact-nativemodalviewcontrollercamera-roll

Why is my camera roll modal empty?


I am attempting to follow the React Native docs on accessing the Camera Roll. I have tried wrapping the camera roll images in a Modal Component. When I press the 'Open Camera Roll' button, the Modal comes up from the bottom with the 'close modal' button visible but none of the images from the camera roll.

When I didn't have it wrapped in a Modal, the images would appear but they would ruin the layout of all the components on my screen, which is why I am (unsuccessfully) trying to place it in a Modal.

Also, if you could give me some tips on how to make the images selectable and appear with 3 images/row it would be greatly appreciated.

    import React from 'react';
    import { CameraRoll, Image, Modal, ScrollView, Text, View } from 'react-native';
    import { Button } from 'react-native-elements';

    export default class AddEvent extends React.Component {
        constructor(props){
            super(props)
            this.state = {
                modalVisible: false,
                photos: [],
            }
        }

        getPhotos = () => {
            CameraRoll.getPhotos({
                first: 100,
            })
            .then(r => this.setState({ photos: r.edges }))
            .catch((err) => {
                alert('Error loading camera roll');
                return;
            });
        }

        openModal() {
            this.getPhotos();
            this.setState({modalVisible:true});
        }

        closeModal() {this.setState({modalVisible:false});}

        static navigationOptions = ({ navigation }) => {
            return {
                headerTitle: (<Text>Camera Roll Test</Text>),
            }
        };

        render(){
        return (
            <View>
                <Modal
                    visible={this.state.modalVisible}
                    animationType={'slide'}
                    onRequestClose={() => this.closeModal()}>
                    <ScrollView>
                        {this.state.photos.map((p, i) => {
                            return (
                                <Image
                                    key={i}
                                    style={{width: 300, height: 100,}}
                                    source={{ uri: p.node.image.uri }}/>
                            );
                        })}
                    </ScrollView>
                    <Button
                        onPress={() => this.closeModal()}
                        title="Close modal"/>
                </Modal>
                <Button
                    onPress={() => this.openModal()}/>
            </View>
        );
    }
}

Solution

  • Got it, needed flex: 1 for <ScrollView> style and a contentContainerStyle. Doesn't look great but the photos show. Credit to u/Mingli91 on reddit.

    import React from 'react';
    import { CameraRoll, Image, Modal, ScrollView, StyleSheet, Text, View } from 'react-native';
    import { Button } from 'react-native-elements';
    
    
    const Dimensions = require('Dimensions');
    const window = Dimensions.get('window');
    const screenWidth = window.width;
    const screenHeight = window.height;
    
    
    export default class AddEvent extends React.Component {
        constructor(props){
            super(props)
            this.state = {
                modalVisible: false,
                photos: [],
            }
        }
    
        getPhotos = () => {
            CameraRoll.getPhotos({
                first: 100,
            })
            .then(r => this.setState({ photos: r.edges }))
            .catch((err) => {
                alert('Error loading camera roll');
                return;
            });
        }
    
        openModal() {
            this.getPhotos();
            this.setState({modalVisible:true});
        }
    
        closeModal() {this.setState({modalVisible:false});}
    
        static navigationOptions = ({ navigation }) => {
            return {
                headerTitle: (<Text>Camera Roll Test</Text>),
            }
        };
    
        render(){
            return (
                <View>
                    <Modal style={styles.modal}
                        visible={this.state.modalVisible}
                        animationType={'slide'}
                        onRequestClose={() => this.closeModal()}>
                        <ScrollView style={{flex: 1}}
                            contentContainerStyle={{ height: 100, width: 300 }}>
                            {this.state.photos.map((p, i) => {
                                return (
                                    <Image
                                        key={i}
                                        style={{width: 300, height: 100,}}
                                        source={{ uri: p.node.image.uri }}/>
                                );
                            })}
                        </ScrollView>
                        <Button
                            onPress={() => this.closeModal()}
                            title="Close modal"/>
                    </Modal>
                    <Button
                        onPress={() => this.openModal()}/>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        modal: {
            flex: 1,
            alignItems: 'center',
            width: screenWidth,
            height: screenHeight,
        }
    });