How To Create a Loading Button in Swift

Build easy and reusable custom loading views

Bruno Lorenzo
4 min readMar 23, 2021
Phone, camera lens and laptop on table
Photo by Maxwell Nelson on Unsplash.

Every time the user interacts with our app, that requires us to do some work (e.g. calling an endpoint or fetching data from the backend). We must let them know that the app is doing something. We should never put the user in a position where they don’t know what is currently happening.

This is why loading animations are so important. They give the user a hint that something is happening in the app at that moment.

One of the most common scenarios is the sign-in button. When the user enters their credentials and taps the button, you probably must interact with the backend to log the user into the app. That process can take a couple of seconds or it could fail due to network problems. It’s a good practice to show the user some kind of loading inside the button.

That is what this article is about. I want to show you how you can make your own loading button with a few lines of code using some Core Animation fundamentals.

Loading animation
GIF by the author.

You can see that the loading consists of three circles that scale up and then return to their original position. So let’s go ahead and create a custom UIView class from scratch that contains the dots to animate.

We can create the dots by creating three custom UIViews and setting their corner radius by half of their width:

The next thing to do is to configure the animations for the dots, and this is when Core Animation comes into action. Think about what the animation actually does: It scales in and then returns to its original size. And this is repeated while the animation is running.

We can achieve this by animating the views recursively with the UIview.animate… API, but I always try to avoid recursive functions unless they’re really necessary. With Core Animation, we can set this animation pretty easily.

First, let’s define three different CABasicAnimation properties (one for each dot) and then do some initial setup:

The most important properties of the setup that you should take a closer look at are:

  • autoreverses: With this set to true, we’re telling the animation to return to its original size once it’s completed.
  • toValue: This is the scale factor that we want to achieve with the animation.
  • repeatCount: Since we want to repeat the animation until it stops, we must set the repeat count to infinity.

Now, in order to start the animation, we need to add our CABasicAnimations to the dots’ layer. To keep things separate, let’s create two functions: startAnimation() and stopAnimation().

We have everything in place to add our DotsAnimationView inside our ViewController’s view and call the startAnimation() to see what happens.

Loading animation

The animations start right after we add them to the layer, so all of them start right at the same time. Luckily for us, we have the beginTime property to set the starting point of our animations. Setting this property can delay the animations to make a sequence effect.

Note: Depending on the animation duration, the delay for the animations may change, but you can play around with some values until it fits your needs.

We only need to create a custom button and add the DotsAnimationView that we just created:

And that’s it! We just need to call the startAnimation() and stopAnimation() functions of our button.

The cool thing about getting the animation in a separate view is that you can use it inside a button or any other view as well. For example, you can use it while fetching some data from the backend to show in a collection view.

Conclusion

I hope this helps you as a starting point. You can get as creative as you want. Maybe your loading doesn’t include the scale transformations but a translation or opacity instead. Whatever you want to do, you can do it yourself. Just keep the separation and reusable principles that we use here in mind so you can use your loading animations not only inside your buttons.

Have any questions? Feel free to drop me a message 🙂. If you like my content, you can subscribe to my Medium page to get notified directly in your inbox whenever I publish a new article.

If you want to support me, you can follow me on GitHub or Twitter.

--

--

Bruno Lorenzo
Bruno Lorenzo

Written by Bruno Lorenzo

Software Engineer | Innovation Manager at www.houlak.com | Former iOS Tech Lead | I write about iOS, tech, and producitivy

No responses yet