In my recent project, I have created custom toggle for baby gender selection. In this post, I would like to demonstrate, how to create such a custom view in SwiftUI and comment it in the order how I usually approach these things.
But first, let’s have a look at what I am aiming for.
Start with Shape
I usually start with the preparation of custom shapes and paths that will be later used in view composition. Drawing shapes using lines and arcs is pretty straightforward, you only need to be cautious about the point coordinates. I always prepare myself small shape annotation on the paper before I start coding.
The Venus shape implementation consists of one ellipse and a set of lines forming the cross below. Note that the center of the bounds is aligned with the center of the ellipse - we will benefit from this later when we will rotate the whole shape.
Shape transformation
Having the basic shape ready, it is time to allow it to transform from the starting Venus symbol to the Mars symbol. Here I will make things easier for me and I will accomplish the transformation from cross to arrow just by moving 4 points like this.
Let’s add a new property called arroweness, that will control the position of transformed points and set it via animatableData property. This will allow SwiftUI to animate the shape whenever we change this property. We expect it to hold values from 0 to 1, where 0 corresponds to a cross symbol and 1 to an arrow symbol.
View Composition
The final Toggle View is Composed from two main views stacked in ZStack:
First, there is a rounded rectangle with gradiend overlay
and on the top there is the gender shape overlayed with white circle, which will make the illusion of actual Toggle.
The code below contains several let constants holding diomensions of the view and subviews. It is ok since the Toggle control usually do not change its size. The meaning of constants is captured on the following diagram:
State switching
By default, both the views are centered along the y-axis. To implement the state switch and changing animation we need to do the following:
add property gender that will hold the state and can be linked to our model via @Binding
change y coordinate of foreground arrow based on the gender value
change our arroweness, rotation and color of gender symbol based on the gender value
add tap gesture recognizer to perform the gender switch
The final code:
Did you like this article?
Feel free to comment or criticise so the next one is even better. Or share it with other SwiftUI adopters ;)