Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

소피아

React Native Switch Toggle Button 리액트 네이티브 스위치 토글 만들기 본문

리액트 네이티브

React Native Switch Toggle Button 리액트 네이티브 스위치 토글 만들기

한희송 2021. 3. 17. 23:47

 

React Native Switch Toggle Button 리액트 네이티브 스위치 토글 만들기


안드로이드랑 아이폰에서 보여지는 네이티브 스위치 토글 버튼 모양이 서로 달라서

두 기기에서 똑같이 보여지도록 직접 만들게 된 컴포넌트를 공유해보려고합니다!

시작해볼까요?

 


우선, 컴포넌트를 마크업을 먼저 만들어볼게요.

ToggleWheel은 스위치의 동그란 부분을 나타내주고, ToggleContainer는 감싸는 부분을 표현해줍니다.

 

<Wrap>
  <Pressable onPress={onToggle}>
    <ToggleContainer style={{ backgroundColor: color }}>
      <ToggleWheel style={[styles.toggleWheel, { transform: [{ translateX: moveSwitchToggle }] }]} />
    </ToggleContainer>
  </Pressable>
</Wrap>

 

스타일컴포넌트로 스타일링을 해주었습니다.

스타일컴포넌트에서 지원되지 않은 부분은 스타일시트를 사용했어요.

const Wrap = styled.View`
  flex-direction: row;
  align-items: center;
`;

const ToggleContainer = styled.View`
  width: 50px;
  height: 30px;
  padding-left: 2px;
  border-radius: 15px;
  justify-content: center;
`;

const ToggleWheel = styled(Animated.View)`
  width: 25px;
  height: 25px;
  background-color: white;
  border-radius: 12.5px;
`;

const styles = StyleSheet.create({
  toggleWheel: {
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.2,
    shadowRadius: 2.5,
    elevation: 1.5,
  },
});

 

기본적으로 스위치 토글에 필요한 props를 받아줍니다.

 isOn, onColor = '#246DFB', offColor = '#E8E8E9', onToggle 
  • isOn: true/false
  • onColor: isOn이 true일 때 색상
  • offColor: isOn이 false일 때 색상
  • onToggle: onPress

 

마지막으로 애니메이션 처리를 해줍니다.

 const [aniValue, setAniValue] = useState(new Animated.Value(0));
  const color = isOn ? onColor : offColor;

  const moveSwitchToggle = aniValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 20],
  });

  Animated.timing(aniValue, {
    toValue: isOn ? 1 : 0,
    duration: 200,
    easing: Easing.linear,
    useNativeDriver: true,
  }).start();

 

 

리액트 네이티브 Animated는 marginLeft에 대한 스타일을 지원 하지 않기때문에 translateX로 대신해주었습니다.

Animated.timing()은 지정된 시간에 easing값에 따라 애니메이션을 적용해주는 함수입니다.

useNativeDriver는 기본값이 false이기 때문에 true를 주어서 부드러운 움직임을 줄 수 있게 해줍니다.

(useNativeDriver는 transform 스타일을 사용할 때 많이 사용합니다.)

 

 

이제! 만든 스위치 토글 버튼 컴포넌트를 사용해봅시당

 <SwitchToggle isOn={toggle.aleam} onToggle={() => handleToggle('aleam', toggle.aleam)} />

 

 const handleToggle = (name, value) => {
    setToggle({ ...toggle, [name]: !value });

    if (name === 'aleam') {
      if (toggle.aleam) {
        Toast.show('2021.02.02 앱 알림 수신을 거부하였습니다.');
      } else {
        Toast.show('2021.02.02 앱 알림 수신을 동의하였습니다.');
      }
    } else if (name === 'bio') {
      if (toggle.bio) {
        Toast.show('생체노노');
      } else {
        Toast.show('생체고고');
      }
    }
  };