Closed gidrokolbaska closed 10 months ago
There is no option to force the Android switch on iOS. Regarding the docs to the MD2, there is a suggestion to keep the platform specific controls in terms of checkboxes or switches – you can read more there
As per guidline yeah any way for some one looking solution ios-switch on both android and ios
import * as React from 'react';
import {
Animated,
Easing,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import PropTypes from 'prop-types';
const ToggleComponent = (props: any) => {
const animatedValue = new Animated.Value(0);
const moveToggle = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 22],
});
const { isOn, onColor, offColor, style, onToggle, labelStyle, label } = props;
const color = isOn ? onColor : offColor;
animatedValue.setValue(isOn ? 0 : 1);
Animated.timing(animatedValue, {
toValue: isOn ? 1 : 0,
duration: 200,
easing: Easing.elastic(0.9),
useNativeDriver: false,
}).start();
return (
<View style={styles.container}>
{!!label && <Text style={[styles.label, labelStyle]}>{label}</Text>}
<TouchableOpacity onPress={typeof onToggle === "function" && onToggle}>
<View
style={[styles.toggleContainer, style, { backgroundColor: color }]}
>
<Animated.View
style={[
styles.toggleWheelStyle,
{
marginLeft: moveToggle,
},
]}
/>
</View>
</TouchableOpacity>
</View>
);
};
ToggleComponent.propTypes = {
onColor: PropTypes.string,
offColor: PropTypes.string,
label: PropTypes.string,
onToggle: PropTypes.func,
style: PropTypes.object,
isOn: PropTypes.bool.isRequired,
labelStyle: PropTypes.object,
};
ToggleComponent.defaultProps = {
onColor: '#000',
offColor: '#ecf0f1',
label: '',
onToggle: () => {},
style: {},
isOn: false,
labelStyle: {},
};
export default ToggleComponent;
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center",
},
toggleContainer: {
width: 50,
height: 30,
marginLeft: 3,
borderRadius: 15,
justifyContent: "center",
},
label: {
marginRight: 2,
},
toggleWheelStyle: {
width: 25,
height: 25,
backgroundColor: "white",
borderRadius: 12.5,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 1.5,
},
});
Thank you, @LeulAria, for the ToggleComponent
.
Here’s a modified version with the following changes and improvements:
props
to align more closely with the Switch
component.useTheme
hook to ensure colors match the selected theme.Animated
API.import React, { useEffect, useRef, useMemo } from "react";
import {
Animated,
Easing,
StyleSheet,
View,
TouchableWithoutFeedback,
} from "react-native";
import { useTheme } from "react-native-paper";
interface ToggleProps {
value: boolean;
onValueChange?: (value: boolean) => void;
disabled?: boolean;
}
const Toggle: React.FC<ToggleProps> = ({
value = false,
onValueChange = () => {},
disabled = false,
}) => {
const animatedValue = useRef(new Animated.Value(value ? 1 : 0)).current;
const moveToggle = useMemo(
() =>
animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [TOGGLE_LEFT_MARGIN, TOGGLE_RIGHT_MARGIN],
}),
[animatedValue]
);
const { primary: trackColorOn, surfaceDisabled: trackColorOff } =
useTheme().colors;
const trackColor = value ? trackColorOn : trackColorOff;
const opacity = disabled ? 0.5 : 1;
useEffect(() => {
Animated.timing(animatedValue, {
toValue: value ? 1 : 0,
duration: 200,
easing: Easing.elastic(0.9),
useNativeDriver: false,
}).start();
}, [value]);
return (
<View style={styles.container}>
<TouchableWithoutFeedback
onPress={disabled ? undefined : () => onValueChange(!value)}
>
<View
style={[
styles.toggleContainer,
{ backgroundColor: trackColor, opacity },
]}
>
<Animated.View
style={[styles.toggleWheelStyle, { marginLeft: moveToggle }]}
/>
</View>
</TouchableWithoutFeedback>
</View>
);
};
export default Toggle;
const TOGGLE_LEFT_MARGIN = 3;
const TOGGLE_RIGHT_MARGIN = 22;
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center",
},
toggleContainer: {
width: 50,
height: 30,
marginLeft: TOGGLE_LEFT_MARGIN,
borderRadius: 15,
justifyContent: "center",
},
toggleWheelStyle: {
width: 25,
height: 25,
borderRadius: 12.5,
shadowColor: "#000",
backgroundColor: "white",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 1.5,
},
});
As the title says, how do I enforce material ui looking Switch in iOS app? I mean, what's the point of the library if on iOS it still looks like an iOS Switch? :)