engineering

Creating a Custom Toggle Switch Component in React Native

Creating a Custom Toggle Switch Component in React Native

A tutorial on how to create a custom toggle switch component in react native to ensure a consistent look and feel across platforms (iOS and Android)

Vaishnav Chandurkar

Vaishnav Chandurkar

Sep 22, 2023 3 min read

React Native provides a wide array of native components that are essential for building mobile applications. However, there are times when you need to create a custom component to match your app's unique design or functionality requirements. In this tutorial, we'll walk you through the process of creating a custom switch toggle component in React Native, using the code you provided.

Why Create a Custom Switch Toggle Component?

  1. Customize Appearance: You can design the switch toggle to match your app's branding, style, and user interface guidelines.

  2. Implement Custom Behavior: You have the freedom to add specific interactions or animations that are not achievable with the default components.

  3. Consistency Across Platforms: Custom components ensure a consistent look and feel across different platforms (iOS and Android) while allowing you to tailor the details to each platform's design guidelines.

Building the Custom Toggle Switch Component

1. Importing Dependencies

import {
	Pressable,
	View,
	Animated,
	SafeAreaView,
	StyleSheet,
} from 'react-native';
import { useEffect, useState } from 'react';
import LinearGradient from 'react-native-linear-gradient';

we are using Pressable for handling user interactions, Animated for animations, and LinearGradient for gradient backgrounds.

2. Component State-wise Styling

We have to define two sets of styles: defaultStyles for the switch in its default state and activeStyles for when the switch is toggled on. These styles are applied to create the gradient background and head of the switch.

const defaultStyles = {
	bgGradientColors: ['#0100ff', '#ff00fb'],
	headGradientColors: ['#ffffff', '#E1E4E8'],
};

const activeStyles = {
	bgGradientColors: ['#00c4ff', '#fff600'],
	headGradientColors: ['#444D56', '#0E1723'],
};

3. Animating and State handling of Custom Switch

const Switch = (props) => {
	const { value, onValueChange } = props;
	const [animatedValue] = useState(new Animated.Value(value ? 1 : 0));

	useEffect(() => {
		// Update the animated value when the value prop changes
		Animated.timing(animatedValue, {
			toValue: value ? 1 : 0,
			duration: 300, // Adjust the animation duration
			useNativeDriver: false,
		}).start();
	}, [value]);

	const translateX = animatedValue.interpolate({
		inputRange: [0, 1],
		outputRange: [4, 28], // Adjust the distance of the switch head
	});

	const toggleSwitch = () => {
		const newValue = !value;
		onValueChange(newValue);
	};

	return (
		...
	);
};

Switch component, which accepts two props: value (the current state of the switch) and onValueChange (a function to handle state changes). You initialize an animatedValue using React State to manage the animation of the switch's head.

The useEffect hook is used to animate the switch's head when the value prop changes. It updates the animatedValue based on the new value, creating a smooth transition effect.

animatedValue.interpolate({...}) defines an interpolation to calculate the translateX value for the switch's head. It ensures that the head moves from one position to another smoothly.

The toggleSwitch function is called when the user presses the switch. It negates the current value and invokes the onValueChange callback with the new value to update the switch state.

4: Rendering the Custom Switch

const Switch = (props) => {
  ...

  const currentStyles = value ? activeStyles : defaultStyles;

  return (
    <Pressable onPress={toggleSwitch} style={styles.pressable}>
      <LinearGradient
        colors={currentStyles.bgGradientColors}
        style={styles.backgroundGradient}
        start={{
          x: 0,
          y: 0.5,
        }}>
        <View style={styles.innerContainer}>
          <Animated.View
            style={{
              transform: [{ translateX }],
            }}>
            <LinearGradient
              colors={currentStyles.headGradientColors}
              style={styles.headGradient}
            />
          </Animated.View>
        </View>
      </LinearGradient>
    </Pressable>
  );
};

StyleSheet

const styles = StyleSheet.create({
 pressable: {
   width: 56,
   height: 32,
   borderRadius: 16,
 },
 backgroundGradient: {
   borderRadius: 16,
   flex: 1,
 },
 innerContainer: {
   flexDirection: 'row',
   alignItems: 'center',
   flex: 1,
   position: 'relative',
 },
 headGradient: {
   width: 24,
   height: 24,
   borderRadius: 100,
 },
});

Using the Custom Switch Toggle Component

const Demo = () => {
	const [isEnabled, setEnabled] = useState(false);

	return (
		<SafeAreaView>
			<View>
				<Switch value={isEnabled} onValueChange={setEnabled} />
			</View>
		</SafeAreaView>
	);
};

Conclusion

Custom toggle switch in react native demo
Demo: Custom toggle switch in react native.

That's it! Wasn't that easy? If you have any questions or feedback. Do let me know. You can find me here on Peerlist.