React-Native

17. React-Native Modal, Switch

Daesiker 2021. 2. 2. 17:05
반응형

1. Modal

Modal 컴포넌트는 모든 View 위에 컨텐츠를 표시해주는 컴포넌트이다.

 

—Example

import React, { useState } from 'react';
import {View, Modal, StyleSheet, Text, TouchableHighlight } from 'react-native';

const App = () => { 
  const [modalVisible, setModalVisible] =useState(false);
  
  return (
    <View style={styles.centeredView}>
      <Modal
        animationType='slide'
        transparent={true}
        visible={modalVisible}
      >
        <View style={styles.centeredView}>
          <View style={styles.modalView}>
            <Text style={styles.modalText}>Hello World!</Text>
            <TouchableHighlight
              //styles.openButton을 복사한뒤 새로운 값 backgroundColor 추가
              style={{ ...styles.openButton, backgroundColor: '#2196F3'}}
              onPress={()=>{
                setModalVisible(!modalVisible)
              }}
            >
              <Text style={styles.textStyle}>Hide Modal</Text>
            </TouchableHighlight>
          </View>
        </View>
      </Modal>
      
      <TouchableHighlight 
        style={styles.openButton}
        onPress={()=> {
          setModalVisible(true)
        }}
      >
        <Text style={styles.textStyle}>Show Modal</Text>
      </TouchableHighlight>
    </View>
  )
}

const styles = StyleSheet.create({
  centeredView: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    marginTop:22,
  },
  modalView: {
    margin: 20,
    backgroundColor: 'white',
    borderRadius: 20,
    padding: 35,
    alignItems: 'center',
    shadowColor: '#000',
    //그림자의 영역 지정
    shadowOffset: {
      width: 0,
      height:2
    },
    //불투명도 지정
    shadowOpacity: 0.25,
    //반경 지정
    shadowRadius: 3.84,
  },
  openButton: {
    backgroundColor: '#f194ff',
    borderRadius: 20,
    padding: 10,
  },
  textStyle: {
    color: 'white',
    fontWeight: 'bold',
    textAlign: 'center',
  },
  modalText: {
    marginBottom: 15,
    textAlign: 'center',
  }
})

export default App;

→ Modal 컴포넌트안에 있는 컴포넌트들은 visible 속성이 true일 때만 보여진다.

→ useState() Hook을 통해 Modal 컴포넌트의 표시 여부를 결정하고 있다.

{ ...styles.openButton, backgroundColor: '#2196F3'}

...

은 styles.openButton을 복사한 뒤 backgroundColor를 추가하는 것이다.

→ shadow 속성은 IOS만 적용 가능하다.

 

 

—Props

  • animationType(enum) : 애니메이션 여부를 결정하는 속성이다.
    1. slide : 슬라이드 형식의 애니메이션
    1. fade : fade in, fade out으로 처리되는 애니메이션
    1. none : 애니메이션 없음
💡
원래는 animated 속성이였지만 사라지고 animationType으로 변경
  • transparent(boolean) : 모달이 표시될 때 전체 배경의 투명도를 결정해준다. true이면 투명한 배경위에 모달이 렌더링되고 false이면 불투명한 배경위에 렌더링 된다.
  • visible(boolean) : true일 때 모달 호출, false일 때 모달 dismiss
  • onShow(function) : Modal이 표시되고 실행할 함수를 정의한다.
  • onDismiss(function) : Modal이 dismiss되는 시점에 실행할 함수를 정의한다.

 

 


2. Switch

스위치를 사용할 수 있는 컴포넌트이다.

자동로그인, 다크모드 같은 기능을 on/off할 때 사용된다.

 

—Example

import React, { useState } from 'react';
import {View, Switch, StyleSheet} from 'react-native';

const App = () => { 
  const [isEnabled, setIsEnabled] = useState(false);
  const toggleSwitch = () => setIsEnabled(!isEnabled);

  return (
    <View style={styles.container}>
      <Switch
        trackColor={{false: '#767577', true: '#81b0ff'}}
        thumbColor={isEnabled ? '#f5dd4b' : '#f4f3f4'}
        ios_backgroundColor= '#3e3e3e'
        onValueChange={toggleSwitch}
        value={isEnabled}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  }
})

export default App;

 

 

—Props

  • value(boolean) : 스위치의 값을 나타낸다 default= false
  • disable(boolean) : 참이면 스위치 사용불가 default= false
  • trackColor() : 스위치 단추의 색을 결정한다.
  • thumbColor(string) : 스위치 배경의 색상을 결정한다.
  • ios_backgroundColor(string) : 스위치가 false일떄의 배경화면을 지정한다.(IOS만 가능)
  • onValueChange(function) : 스위치의 값이 변경될 때 실행할 함수 정의

 

 


<로그인 창 만들기>

import React, { useState } from 'react';
import {View, 
        KeyboardAvoidingView, 
        TextInput, 
        StyleSheet, 
        Switch, 
        Platform, 
        TouchableWithoutFeedback, 
        Text, 
        Keyboard, 
        Image, 
        SafeAreaView, 
        TouchableHighlight,
        Modal
} from 'react-native';

const App = () => {
  const [isEnabled, setIsEnabled] = useState(false)
  const [ID, setID] = useState('')
  const [password, setPassword] = useState('')
  const [signInModal, setSignInModal] = useState(false);
  const [loginModal, setLoginModal] = useState(false);

  const toggleSwitch = () => setIsEnabled(previousState => !previousState);

  return (
    
    <SafeAreaView style={styles.container}>
      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : "height"}
        style={{...styles.container, paddingBottom: 15}}
      >
        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
          <View style={styles.inner}>
            <View style={styles.imageView}>
              <Image style={styles.image} source={{uri:'https://raw.githubusercontent.com/wjseotlr12/Take-Off/main/Take-Off/Resources/Assets.xcassets/logo.imageset/logo.png'}}/>
            </View>
            <TextInput style={styles.textinput}
              placeholder="Username"
              onChangeText={text => setID(text)} value={ID}
            />
            <TextInput style={styles.textinput}
              placeholder="Password"
              onChangeText={text => setPassword(text)} value={password}
            />
            <View style={styles.switchView}>
              <Text style={styles.switchText}>자동 로그인</Text>
              <Switch
                style={{marginLeft: 10}}
                value={isEnabled}
                trackColor={{true: 'orange'}}
                onValueChange={toggleSwitch}
              />
            </View>
            <TouchableHighlight 
              onPress={() => setLoginModal(true)}>
              <View style = {styles.btnContainer}>
                <Text style={styles.textStyle}>Log In</Text>
              </View>
            </TouchableHighlight>
            <TouchableHighlight
              style={{marginTop: 15}}
              onPress={() => setSignInModal(true)}
            >
              <View style = {styles.btnContainer}>
                <Text style={styles.textStyle}>Sign In</Text>
              </View>
            </TouchableHighlight>
          </View>
        </TouchableWithoutFeedback>
      </KeyboardAvoidingView>
      <Modal
      animationType='slide'
      transparent={true}
      visible={signInModal}
    >
      <View style={styles.centeredView}>
        <View style={styles.modalView}>
          <Text style={styles.modalText}>준비중 입니다.</Text>
          <TouchableHighlight
              style={styles.openButton}
              onPress={() => {
                setSignInModal(!signInModal);
              }}
            >
              <Text style={styles.textStyle}>Close</Text>
            </TouchableHighlight>
        </View>
      </View>
    </Modal>
    <Modal
        animationType='slide'
        transparent={true}
        visible={loginModal}
      >
        <View style={styles.centeredView}>
          <View style={styles.modalView}>
            <Text style={styles.modalText}>{ID === '' ? 'Error!' : `Welcome ${ID}!`}</Text>
            <TouchableHighlight
                style={styles.openButton}
                onPress={() => {
                  setLoginModal(!loginModal);
                }}
              >
                <Text style={styles.textStyle}>Close</Text>
              </TouchableHighlight>
          </View>
        </View>
      </Modal>
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  container: {
    flex:1
  },
  imageView: {
    alignItems: 'center'
  },
  image: {
    width: 100,
    height: 100,
  },
  inner: {
    padding:24,
    flex:1
  },
  textinput: {
    marginTop: 20,
    height: 40,
    borderColor: "orange",
    borderBottomWidth: 1,
    marginBottom: 10,
  },
  switchText: {
    marginTop: 6,
    fontSize: 14
  },
  switchView: {
    marginBottom: 15,
    flexDirection: 'row'
  },
  btnContainer: {
    padding: 15,
    alignItems: 'center',
    borderRadius: 10,
    backgroundColor: 'orange',
    borderColor : 'black',
    borderWidth: 1
    
  },
  textStyle: {
    fontSize: 20,
    color: 'white',
    fontWeight: 'bold',
    textAlign: 'center',
  },
  centeredView: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 22
  },
  modalView: {
    margin: 20,
    backgroundColor: "white",
    borderRadius: 20,
    padding: 35,
    alignItems: "center",
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5
  },
  openButton: {
    backgroundColor: "#F194FF",
    borderRadius: 20,
    padding: 10,
    elevation: 2
  },
})

export default App;

 

→ 지금까지 공부한걸 토대로 로그인 창을 구현해보았다.

→ 코드가 아주 더럽다....

반응형