Swift Components Tour – Progress And Activity

In this lesson

This chapter of the Swift Components Tour is progress and activity. Make waiting fun for your user! … Or at least keep them informed on remote processes.

Kyle Roberts
Swift Guru at Large

Kyle's Series


Tap on time to skip ahead


Hello world and welcome to another stop on the Swift Components Tour. Today’s stop is Progress and Activity. This third section called Advanced Interaction, you may notice that the items are not labeled with their UIControl item or their UIKit class. That is because of one of two reasons. Either that stop on the tour is utilizing more than one object from UIKit, such as Progress and Activity, or that stop on the tour is not using UIKit at all. Stay tuned and you’ll find out!


But anyways, back to Progress and Activity. Here we have what looks like a label except it’s blue. In iOS8 we know that is a UIButton. It says Start. We have what looks like a halted spinner, it’s not spinning, and then a grey line. Going by the name of this view controller, Progress and Activity, you can probably guess that we’ve pressed the Start button. The spinner will start spinning and the progress bar will start progressing. You guessed correctly!


We press the Start button, you can see the spinner is spinning and the progress bar is slowly filling up the grey line with blue. When the progress bar fills all the way up and has reached the end of its progress, then the spinner will automatically stop, and the Start button which had changed to say Continue will go back to Start. What happens when we hit the Start button again is it will start from the beginning and the button changes to Stop. We can tap it when it says Stop and it will stop the spinner and the progress bar without resetting anything. Notice that the progress bar is still about halfway full, if we press Continue, it will run for a little bit until we press Stop and stop again. If we press Continue and let it finish, it will go back to saying Start again. If we press Start, it will just start over. Pretty simple.


A lot of the time when you will be using either of these views, you may be using them together, you may not. Usually the UIActivityIndicator, which is the name of the class of the spinner, let’s the user know that there is something that they have to wait on to use a part of the app. You can just display it in the corner, you can display it in the status bar. Or you could create a larger one that goes over the middle of the screen to stop any user interaction until that process has finished. Just a way to communicate to the user that your app is doing something.


The progress bar is fairly self explanatory. The grey area of the bar is obviously the progress you are trying to reach. The blue is the progress that you have covered. Where they separate, where the blue ends, is your current percentage of the download or whatever action is taking long enough that you decided to use a progress bar. Often times, you will have a progress bar hooked up to some report calls from a remote source or maybe as you’re downloading something you’re doing the math yourself in the app, saying I have so many kilobytes of this so many kilobyte file and updating the progress bar based on that percentage. All that means is whenever a user sees either of these elements in an app, they’re going to know what it means.


You can see over here on the storyboard, it looks exactly the same as what you see in the app.  Just the view controller size is smaller in the storyboard, but that goes for each of the views. There’s nothing special going on here. Just a Start button, normal UIActivityIndicator and a UIProgressView. If I customized them at all, it was not very much, other than just some auto layout constraints to set them in the center of the screen like this and then adding references to their ViewController. You can see here we have the Start button, activityIndicator and the progressBar. I also have two other properties in this class. One isLoading, which is a bool, and a timer, which is an NSTimer. Here we have an IBAction from the button. When the button is tapped we ask, “If self is not loading,” which is that bool up here, “then we will start spinning the activityIndicator, we will startProgress,” which is another method I have below which sets up the progress bar to go from 0-100%, “then we’ll change the text on the Stop button.” If the button is tapped and we are loading, and the isLoading bool is true, then we want to stop the spinner and stop the progress bar.


The start and stop progress methods down here are what are handling the setup of the progress bar. Here in startProgress we see, if the progress is full then we want to set it to zero. The progress is a value between zero and one. Then we will set isLoading to true and start an NSTimer, which calls this incrementProgressBar method every 0.01 seconds. In this incrementProgressBar method we will set the progress bar’s current progress to add 0.001 to it’s value. Remember it’s a value between zero and one. So from start to finish the progress bar here will take ten seconds to fill all the way up. Once it has filled up, and we’re checking that by asking if the current progress is equal to one, then we’ll stop the spinner and we’ll call this method stopProgress. In this method, we are invalidating the timer, which stops it from calling this incrementProgressBar method, setting isLoading to false, then just setting the button text based on the current status of the progress bar. Again, because we can stop it early in this buttonTapped method, say we stopped it at 50%, we’re calling the stopProgress button, if the progress bar is not full then we change the title to Continue. We’re only resetting the progress bar back to zero in the startProgress method if the progress bar is already full.


So that’s just a bunch of logic for a quick display of the progress bar filling up in ten seconds. If you’re using it with a remote action or a download process or something, it’s not going to always be ten seconds. The time it takes to fill the progress bar or even the speed over that time is going to differ based on the current action that you’re monitoring. You’ll be implementing your own back and forth like this, but probably a little more complicated since you’ll be dealing with other sources, instead of this being a closed environment in just this class. Thanks for watching!

Additional Info

Register to get access to additional resources and info.