유미의 기록들

[React Native -20] Modal 구현 본문

MDLAB 기록/차량부품거래애플리케이션

[React Native -20] Modal 구현

지유미 2023. 1. 2. 20:00
728x90
반응형

상품이미지를 등록할 때 사진을 카메라에서 촬영할 지 아니면 갤러리에서 선택할 지 사용자가 선택하도록 모달을 띄어보려고 한다.

 

 

React Native에서는 Modal이라는 컴포넌트를 제공한다 따라서 import해서 사용할 수 있다

https://reactnative.dev/docs/modal

 

Modal · React Native

The Modal component is a basic way to present content above an enclosing view.

reactnative.dev

 

import {Modal} from 'react-native';
class AddGoods extends Component {
    constructor(props) {
        super(props);

        this.state = {
            ImageSelectorPopupVisiable:false, //상품이미지 팝업메뉴 모달  
            ...
        }
    }

 

 

// 카메라 버튼 클릭
goodsCameraButtonClicked = () => {
    this.setState({ImageSelectorPopupVisiable:true})
}

 

 <Modal
    animationType='fade' 
    transparent={true} 
    visible={this.state.ImageSelectorPopupVisiable}
    onRequestClose={() => this.setState({ ImageSelectorPopupVisiable:false})}>
    <ImageSelectorPopup x={this.cameraModalX} y={this.cameraModalY} 
    closeCameraPopupMenu={() => this.setState({ ImageSelectorPopupVisiable:false})}
    goCameraScreen={this.goCameraScreen} goGalleryScreen={this.goGalleryScreen}/>
</Modal>

 

 

 

Modal의 속성들

animationType

모달 화면을 띄울 때 애니메이션 방식을 정할 수 있다

 

transparent

모달화면을 투명하게 할 것인지 정할 수 있다

 

visible

모달 화면을 보이게 할 것인지 숨길 것인지 정할 수 있다

* 상태 변수인 cameraPopupMenuVisiable값이 true일때 모달화면이 뜨고 false일 때 모달화면이 안뜨게 된다.

 

 

onRequestClose

뒤로가기 할 경우 모달창을 없앨 수 있다

 

class ImageSelectorPopup extends Component{
    constructor(props) {
        super(props);
    }
    render(){
        const layout={flex:1 ,left:this.props.x,top:this.props.y};
      return(
        <>
            <TouchableOpacity onPress={this.props.closeCameraPopupMenu} style={{flex:1}}>
                <View style={layout} >
                    <TouchableWithoutFeedback>
                    <View style={styles.cameraModalView}>
                        <View style={styles.cameraView}>
                            <TouchableOpacity  onPress={this.props.goCameraScreen}>
                                <View style={{flexDirection:'row'}}>
                                <IconPopup name="camera" size={25} color={'black'} ></IconPopup>
                                <Text style={styles.modal_text}>카메라   </Text>   
                                </View>
                            </TouchableOpacity>
                        </View>
                        <View style={styles.galleryView}>
                            <TouchableOpacity onPress={this.props.goGalleryScreen}>
                            <View style={{flexDirection:'row'}}>
                            <IconPopup name="image" size={25} color={'black'} ></IconPopup>
                            <Text style={styles.modal_text}>앨범</Text>
                            </View>
                            </TouchableOpacity>
                        </View>
                    </View>
                    </TouchableWithoutFeedback>
                </View>   
            </TouchableOpacity>    
        </>
      )
    }
}

 

✔️ 모달 화면 밖을 터치했을 때 닫기

모달화면을 둘러싼 전체화면를 버튼(TouchableOpacity)으로 하여 모달화면 밖의 영역을 눌렀을 경우,  AddGoods 클래스에서 구현해놓은 closeCameraPopupMenu함수를 호출해서 모달이 닫히도록 하였다.

TouchableWithoutFeedback을 사용하여 보이는 부분의 모달화면은 그 버튼이 실행되지 않게 하였다.

 

 

✔️ 모달 위치 설정

카메라 버튼의 오른쪽 아래에 걸치도록 위치를 설정 하고싶었다. 따라서 카메라 버튼의 사이즈와 좌표를 알아야겠다고 판단했다

class AddGoods extends Component {
    constructor(props) {
        super(props);
  		// 팝업메뉴위치
        this.cameraIcon=React.createRef();
        this.cameraModalX=null;
        this.cameraModalY=null;
    }
<View onLayout={(event)=>{ this.getViewSize(event)}}  ref={this.cameraIcon}>
    <TouchableOpacity style={styles.btn_camera} onPress={this.goodsCameraButtonClicked}>
        <IconCamera name="camera" size={30} color={'black'}></IconCamera>
        <Text><Text style={styles.text_count}>{this.state.imageURLs.length}</Text>/5</Text>
    </TouchableOpacity>
</View>

 

카메라 버튼이 있는 View에 onLayout을 활용해서 x,y좌표와 너비를 알아내서 모달이 위치해야 할 곳을 계산하였다

getViewSize=()=>{
    this.cameraIcon.current.measure((fx,fy,width,height,px,py)=>{
        this.cameraModalX=px+width/1.5;
        this.cameraModalY=py+height/2;
        console.log('location:',fx,fy,width,height,px,py)
    })
}

 

 

 

문제발생) 원하는 위치에 모달화면을 띄울 수 있었지만, 스크롤을 내리고 버튼을 클릭했을때는 모달화면이 올라가지 않고 고정되어 있는 문제가 있었다

 

 

→ 스크롤의 위치를 감지해서 y좌표로 두어야 겠다고 판단했다 

스크롤 속성 중에 onScroll 을 사용해서 y좌표를 getViewSize함수로 넘겨주었다

<ScrollView
    onScroll={event=>{
        this.getViewSize(event.nativeEvent.contentOffset.y);
}}>

 

728x90
반응형
Comments