본문 바로가기

react-native

[RN] react-native-pin-view PIN CODE 구현

react-native-pin-view PIN 번호 기능 구현

PIN 번호 입력,재입력 후 keychain에 저장해 확인까지 하는 기능 구현

 

keychain 및 Icon 활용은 아래 글 참고

2023.08.09 - [react-native] - [RN] react-native-keychain 구현

2023.08.11 - [react-native] - [RN] react-native-vector-icons 사용하기


react-native-pin-view 설치

npm install --save react-native-pin-view
cd ios 
pod install

 

RegisterPinCodeScreen.js

PIN 번호 등록, 재확인 화면

import React, { useEffect, useRef, useState } from "react"
import { ImageBackground, SafeAreaView, StatusBar, Text, Alert, TouchableOpacity } from "react-native"
import ReactNativePinView from 'react-native-pin-view';
import Icon from "react-native-vector-icons/Ionicons"
import * as keyStore from '/lib/secure-key-store';

const RegisterPinCodeScreen = (props) => {
  const pinView = useRef(null)
  const [showRemoveButton, setShowRemoveButton] = useState(false)
  const [showCompletedButton, setShowCompletedButton] = useState(false)
  const [enteredPin, setEnteredPin] = useState("")
  const [step1Pin, setStep1Pin] = useState("")
  const [step, setStep] = useState('1');

  useEffect(() => {
    if (enteredPin.length > 0) {
      setShowRemoveButton(true)
    } else {
      setShowRemoveButton(false)
    }
    if (enteredPin.length === 6) {
      setShowCompletedButton(true)
    } else {
      setShowCompletedButton(false)
    }
  }, [enteredPin])
  return (
    <>
      <StatusBar barStyle="light-content" />
        <SafeAreaView
          style={{ flex: 1, backgroundColor: "rgba(0,0,0,0.5)", justifyContent: "center", alignItems: "center" }}>
          <Text
            style={{
              paddingTop: 24,
              paddingBottom: 48,
              color: "rgba(255,255,255,0.7)",
              fontSize: 48,
            }}>
            {step === '1' ? 'PIN 등록' : 'PIN 확인'}
          </Text>
          <ReactNativePinView
            inputSize={32}
            ref={pinView}
            pinLength={6}
            buttonSize={60}
            onValueChange={value => setEnteredPin(value)}
            buttonAreaStyle={{
              marginTop: 24,
            }}
            inputAreaStyle={{
              marginBottom: 24,
            }}
            inputViewEmptyStyle={{
              backgroundColor: "transparent",
              borderWidth: 1,
              borderColor: "#FFF",
            }}
            inputViewFilledStyle={{
              backgroundColor: "#FFF",
            }}
            buttonViewStyle={{
              borderWidth: 1,
              borderColor: "#FFF",
            }}
            buttonTextStyle={{
              color: "#FFF",
            }}
            onButtonPress={key => {
              if (key === "custom_left") {
                pinView.current.clear()
              }
              if (key === "custom_right") {
                if(step === '1'){
                  setStep('2');
                  setStep1Pin(enteredPin);
                  setEnteredPin('');
                  pinView.current.clearAll();
                }else{
                  if(step1Pin === enteredPin){
                    Alert.alert('일치', '', [{text: '확인', onPress: () => {
                        keyStore.setItem('pincode', enteredPin);
                        props.navigation.goBack();
                        }
                      }]
                    );
                  }else{
                    Alert.alert('불일치');
                  }
                }
              }
            }}
            customLeftButton={showRemoveButton ? <Icon name={"arrow-back-outline"} size={36} color={"#FFF"} /> : undefined}
            customRightButton={showCompletedButton ? <Icon name={"arrow-forward-outline"} size={36} color={"#FFF"} /> : undefined}
          />
        </SafeAreaView>
    </>
  )
}

export default RegisterPinCodeScreen;

 

PINCodeScreen.js

PIN 번호를 입력 받아 keychain에 저장한 번호와 일치하는지 확인

import React, { useEffect, useRef, useState } from "react"
import { ImageBackground, SafeAreaView, View, StatusBar, Text, Alert, TouchableOpacity} from "react-native"
import ReactNativePinView from 'react-native-pin-view';
import Icon from "react-native-vector-icons/Ionicons"
import * as keyStore from '/lib/secure-key-store';

const PINCodeScreen = (props) => {
    const pinView = useRef(null)
    const [showRemoveButton, setShowRemoveButton] = useState(false)
    const [enteredPin, setEnteredPin] = useState("")
    const [pin, setPin] = useState("")

    keyStore.getItem('pincode').then((pinNumber) => {
        if (pinNumber) {
          setPin(pinNumber);
        }
    });

    useEffect(() => {
      console.log('pinnn :: ', pin)
      if (enteredPin.length > 0) {
          setShowRemoveButton(true)
      } else {
          setShowRemoveButton(false)
      }

      if (enteredPin.length === 6) {
        if(enteredPin === pin){
          Alert.alert('일치', '', [{text: '확인', onPress: () => {
              props.navigation.goBack();
              }
            }]
          );
        }else{
          Alert.alert('PIN 번호가 일치하지 않습니다.', '', [{text: '확인', onPress: () => {
              pinView.current.clearAll();
              }
            }]
          );
        }
      }
  }, [enteredPin])
  return (
    <>
      <StatusBar barStyle="light-content" />
        <SafeAreaView
          style={{ flex: 1, backgroundColor: "rgba(0,0,0,0.5)", justifyContent: "center", alignItems: "center" }}>
          <Text
            style={{
              paddingTop: 24,
              paddingBottom: 48,
              color: "rgba(255,255,255,0.7)",
              fontSize: 48,
            }}>
            PIN 확인
          </Text>
          <ReactNativePinView
            inputSize={32}
            ref={pinView}
            pinLength={6}
            buttonSize={60}
            onValueChange={value => setEnteredPin(value)}
            buttonAreaStyle={{
              marginTop: 24,
            }}
            inputAreaStyle={{
              marginBottom: 24,
            }}
            inputViewEmptyStyle={{
              backgroundColor: "transparent",
              borderWidth: 1,
              borderColor: "#FFF",
            }}
            inputViewFilledStyle={{
              backgroundColor: "#FFF",
            }}
            buttonViewStyle={{
              borderWidth: 1,
              borderColor: "#FFF",
            }}
            buttonTextStyle={{
              color: "#FFF",
            }}
            onButtonPress={key => {
              if (key === "custom_left") {
                pinView.current.clear()
              }
              if (key === "custom_right") {
                props.navigation.goBack();
              }
            }}
            customLeftButton={showRemoveButton ? <Icon name={"arrow-back-outline"} size={36} color={"#FFF"} /> : undefined}
            customRightButton={<Icon name={"arrow-forward-outline"} size={36} color={"#FFF"} />}
          />
        </SafeAreaView>
    </>
  )
}

export default PINCodeScreen;

 

참고사이트 

https://www.npmjs.com/package/react-native-pin-view

 

react-native-pin-view

React Native Pin View Component for Protection. Latest version: 3.0.3, last published: 8 months ago. Start using react-native-pin-view in your project by running `npm i react-native-pin-view`. There is 1 other project in the npm registry using react-native

www.npmjs.com