解決此種問題的方式有很多
-
可以導入原生庫
react-native-switch
-
切圖 (會缺少動畫)
-
使用 js 組件
這里使用 js 繪制組件(原生體驗)解決此類問題
Switch.tsx
import React, { useEffect, useRef, useState } from 'react';
import { Animated, Pressable, StyleSheet } from 'react-native';interface SwitchProps {value?: boolean;onChange?: (value: boolean) => void;
}const Switch: React.FC<SwitchProps> = ({ value = false, onChange }) => {const switchAnim = useRef(new Animated.Value(0)).current;const switchHandle = () => {onChange?.(!value);};useEffect(() => {const toValue = value ? 23 : 3;Animated.timing(switchAnim, {toValue,duration: 100,useNativeDriver: false, // 此處原生驅動會導致 ios 顏色顯示不對}).start();}, [switchAnim, value]);const backgroundColor = switchAnim.interpolate({inputRange: [0, 25],outputRange: ['#D2D2D2', '#904FF5'],});return (<Pressable onPress={switchHandle}><Animated.View style={[styles.radioContainer, { backgroundColor }]}><Animated.View style={[styles.radio, { transform: [{ translateX: switchAnim }] }]} /></Animated.View></Pressable>);
};const styles = StyleSheet.create({radioContainer: {width: 52,height: 32,borderRadius: 17,justifyContent: 'center',marginRight: 5,},radio: {width: 25,height: 25,backgroundColor: '#FFFFFF',borderRadius: 15,},
});export default (props: SwitchProps) => {const [value, setValue] = useState(props.value || false);// 監聽 props.value 的變化并更新內部狀態useEffect(() => {setValue(props.value ?? false);}, [props.value]);return (<Switchvalue={value}onChange={() => {props.onChange?.(!value);}}/>);
};
用法
<Switch value={value} onChange={(value: boolean)=>{}} />