These 3 Practices by Bill Gates Will Change How You Read

Reading gives you access to the smartest brains on earth. Learning from the greatest people is the fastest way to become healthy, wealthy, and wise. Charlie Munger, self-made billionaire, and Warren…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




How to create Timer and Animations in SwiftUI

It has been almost a year since Apple announced the SwiftUI framework which was supposed to facilitate and speed up the process of building user interface across all Apple devices’ platforms. More of that, SwiftUI is capable to support automatically dynamic type, dark mode, accessibility and localisation which means that developers don’t need to implement these features with extra work.

So, our team being young developers and having some experience of working mainly with UIKit was very excited and curious to create a project based on the SwiftUI framework only. We also wanted to challenge ourselves with building something dynamic and functional at the same time. That’s why we came up with an idea to create animation views combined with a Timer function. We thought that it could be one of the most efficient and shortest ways to have a basic idea of working with declarative programming.

As you know, using declarative syntax could simplify your work only if you have a clear image about what you want to accomplish using code rather than how you want to make it done. It was a pretty unusual way for us to define the final result from the beginning. Besides, it often happens that each member of the team has a different idea of the final outcome. So, for us it was also the important to improve the skills of listening and cooperating. Nevertheless we hoped that SwiftUI could understand what we wanted it to do since at least it also speaks English as we do (and by the way its English writing skills are maybe better than UIKit ones).

Thus, we came up to an agreement that the final result of our project should contain a countdown timer set with a picker and two animations which will appear after the timer starts counting and will finish when counting ends. Here are some pictures of the outcome:

Creating a Timer

Firstly we decided to figure out how to build the timer function on SwiftUI. Timer has mainly three parts to do that. The first step is declaration, then you need to fire your timer and finally add a stop function. Let’s create a timer. We start with two variables:

We use @State for this variables because we will work on one view. After that we will need buttons for user actions like Start, Stop and Reset. We create the buttons in an HStack (Later we will add a ZStack for the Start and Stop buttons because we want to change one to another). Put the code below inside the Start button’s action:

and we need to add .invalidate() so that the timer will not be running forever. Add to the Stop button:

Finally, to reset the timer we assign the initial value again:

So that’s all. If we add text to display the selectedSecs, the timer is ready. This is so easy, right? Ok that’s not enough for building a timer app. We need the user to choose a value for the timer. Apple uses pickers in its native timer app so there is no need to do research about a better way.

We will create three pickers for the timer. Let’s make three different arrays:

and add two variables for the minutes and the hours;

In SwiftUI creating a picker is really easy, just add some parameters like:

The only point is here is that we need to add “$” to the selection parameter because of two way binding for data. We do the same for the minutes and the hours. We can place all the pickers in an HStack, its ok for now but we need to adjust their sizes to the screen. Adding GeometryReader can help for this.

The next step is calculating the total seconds. We create a function:

With this function, we want to stop our timer when it comes to zero. Add these lines of code to the Start button:

It’s going well but the user can’t see the timer yet. Now we add Text embedded inside another HStack to our VStack:

Maybe it seems weird but trust us, it works. For minutes and seconds we use remains(%) in calculations. Specifier: “%02d” means that it changes “0” to “00”. This type is better to be used in the timer app.

Before starting to make the animations, we need two Booleans to hide the buttons and the pickers:

Finally we add .opacity() with these Booleans to the Start-Stop Buttons and our three pickers. Now we are ready to create animations.

Creating our animations

Once we have finished the timer, it’s time to create our animations now! We wondered which kinds of animations would be suitable to depict the time progress.

We came up with two different types:

Growing and shrinking objects

Our idea is to create two ellipse objects, placing one on the top and the other one on the bottom of the view. When the timer starts, only the upper one should be visible and start to shrink. In parallel, the ellipse on the bottom will start to grow until it reaches the original size of the upper ellipse. Later, we would add a drop-similar ellipse to illustrate the matter moving from one ellipse to the other. (We will not describe the details of the drop in this article because the logic is the same as for our second animation of dropping objects).

So, how to make the ellipses change their size smoothly?

To start, we add two ellipse views to the body View of our ContentView, embedding them in a VStack together. In order to determine their size, we add a .frame modifier to each of them. Because we want their size to change, we use variables for the width and height which we declare as @State variables in the top of our Content View. We directly initialise them, giving the ellipses their initial size. When the timer will be started, their new size will be set. We will come to that later.

Now the questions is: how can we make the ellipses change from their old to their new size in a smooth animation? We simply need to add the .animation modifier, precise the type of animation choosing .easeInOut with a duration of 1.5 seconds. The ellipses will now grow or shrink smoothly until reaching their new size. That’s the magic of SwiftUI!

Objects dropping down

The idea of the second animation is to create plenty of balls and make them fall down until they fill up the entire view. So, here the challenge is: How can me make the balls move from one position to another?

We start by creating a struct of type View where we define all the properties of our balls, including .offset which allows us to set their position. Then we create many instances of it in the body of our Content View, one for each ball. Now, how should we place them in the view?

We decided to make several rows with each row containing four or five balls. In the beginning, they will be placed above the view, so not be visible. When the timer starts, their new position will be set to a dedicated place within the view. To make the animation more interesting, we will also attribute to each of the balls a different type of animation (.easeIn, .easeOut or .easeInOut) as well as a different duration of the animation. This will make them fall down with a different speed.

Here is what the creation of the balls looks like in code. The durationFactor variable will be important in the next part. (We created a lot more balls than shown here. And yes, all “by hand” with different duration and position. We could not find a way yet to create them programmatically, giving them the values randomly. But there should be a way, right?)

Combining animations with timer

The last step consists in combining the animations with the timer. To start, we need to set the values for the new sizes of the ellipses and the new positions of the balls. But where is the best place to do this? We think it is inside the action of the “Start” button since this also launches the timer.

In addition to this, the ellipses should keep growing and shrinking as long as the timer is running and the balls should reach their end position when the timer reaches zero. You see where this is going? We need to apply some maths!

For the ellipses, we need to calculate how much their size should increase or decrease each second. We do that by dividing the total number of seconds by the selected maximal width and the maximal height, in our case 400 and 300. We then add or subtract this amount to or from the respective width and height of the two ellipses each second until the timer is finished and we reach our final sizes.

For the balls, we need to calculate how fast they should fall down, so that they use the whole duration of the timer. Since we attributed an individual duration of the animation to each ball, we will determine a duration factor to multiply the individual duration with. This duration factor is the result of the initial number of total seconds divided by the longest attributed duration, in our case it’s 5.5.

Finally, when the timer reaches zero, we set the values back to the original ones. We should do the same in the action of the “Reset” button.

Here is the code we added to the “Start” button in order to launch the animations:

^ Ellipses Animation

^ Balls Falling Animation

Now, after the project is finished we can say that SwiftUI is a great and fast way to create animations. The working process could be very interactive, exciting and interesting for developers. Maybe for those who are just starting learning to code, SwiftUI could be confusing at the beginning because of its complex architecture. But for more experienced developers it is definitely the way to improve and facilitate the process of creating applications. We also have the impression that building a whole application with SwiftUI could be challenging. But as soon as it would be implemented by developers more commonly we believe that SwiftUI could take the coding process to the next level.

So the main goal for us was to learn the basic principles of the SwiftUI framework through creating animations with a timer function. Since we did not have experience of using SwiftUI we spent some time on learning the declarative syntax of this framework following Apple’s official tutorials and others we could find. Nevertheless, after that it was still quite challenging to figure out how to build the countdown timer and then how to combine it properly with the animation views. We can say that we achieved our goal and more of that we learned how to collaborate efficiently and remotely (as half of the world population because of COVID-19), organise our team work with splitting different tasks, listening to each other and accomplishing the challenge step by step.

Here are the links to our project’s Git Repositories:

This article was written by three students of Apple Developer Academy:

Ana Sofia Caballero, Ahmet Ceylan and Gerel Burgustina

Add a comment

Related posts:

A Day with Lou Ortenzio

The second Lou Ortenzio steps out of the car a passerby shouts “hello.” As he enters the hospital’s doors another person greets him. He barely makes it to the desk before someone else addresses him…