Making a loading spinner in Swift is as easy as dropping an activity indicator from your object library to your storyboard and connecting it to your code. But what if you want to give your app a little extra style? A custom loading indicator is a great little touch that can help set your app apart from the crowd.Creating a custom spinner is not much harder than using the default activity indicator. The basic steps are as follows:

  • Draw vector shape in Photoshop
  • Import to After Effects
  • Animate Icon
  • Export as PNG sequence
  • Import to XCode
  • Set up animated spinner

The loading indicator we’ll be working on today is a chat icon. This could be used for loading a chat app, a conversation, or maybe a typing indicator for a custom chat view. > I’m using an icon from our UI Font – Line Style. The icon font makes it really easy to find and place icons in your designs. Instead of searching through the Illustrator or Photoshop files, you can just type the icon name. In this case, I typed “chat-dots” and got this 3-dot chat icon. Convert the text to a shape and you’ll have a nice chat icon shape layer. Since you might not have the icon font yet, I included a psd with this one icon in it The After Effects file you’re about to create is in there as well, for reference.

Download Source Files

Base Icon PSD

Open After Effects and import the icon psd as a composition. Double-click the chat composition in your project panel and you’ll see the background layer and the icon layer. After Effects doesn’t always know the right way to import paths (add/subtract etc) so you’ll have to adjust the mask order and the pathfinding mode. Think of the masks as the layers in Illustrator or Sketch and it might be easier to figure out whether to use Add or Subtract. I normally start from the outside edge of the icon and work my way in.

Before and After AE mask adjustments

I’d like the icon to be a nice blue that matches our UI8 logo. Right-click on the icon layer and go to Effect->Generate->Fill. Change the red color to #1995F9.

Rename your icon layer to “chat bubble”. Duplicate the layer and rename that to “chat dot”. To make this easier to animate we’re going to separate the dots and chat outline. It’s a lot less complex than animating masks, especially in a case like this where we’ll have a duplicated motion. Your timeline should now have three layers: chat dot, chat bubble, and background.

Timeline and blue fill set up

On the “chat dot” layer, select all the masks except Mask 3, and delete them. It’s going to be a lot easier to animate one dot and then duplicate it twice, rather than animating three masks. Select the Pan Behind tool, and move the anchor point for the dot layer to the middle of the dot. Set an initial keyframe for Position, Scale and Opacity of the dot layer. We’re about to walk through the specifics of how to animate these dots. It’s a fairly simple animation.

At 10 frames (10f), move the dot up slightly, about one dot’s height. Change Scale to 140%, and Opacity to 0%. The dot should now rise, grow, and fade out over a 10 frame span. Move one frame forward (11f), and copy/paste the original Position keyframe. Select the first Position keyframe copy it, and paste it on frame 11.

Now, just move the dot down slightly, about half-dot-height. Change the scale to 80%, and leave the Opacity at zero. Move the playhead to frame 19 (19f), and copy/paste the original keyframes from frame zero, for all three properties. You should now have the animation loop set up for a single dot.

Chat dot with keyframes

To finish the animation loop, just duplicate the dot layer twice, so you have a total of 3. To move the dots over, you’ll have to select all the position keyframes. Otherwise, you’ll just add a new keyframe or edit the one you’re currently on. Select all the position keyframes for one of the dot layers, and move the dot to the middle position. Do the same for the third dot, but move it to the end position.

The last thing to do is stagger the animations. I simply move all the keyframes by about 5 for the 2nd dot, and 10 for the 3rd dot. To make it easier to see, select the three dot layers and hit “u”. This will show all the keyframes for those selected layers. Offset the animations, then select all the keyframes and hit F9 to apply a simple Easing motion to the animation, just to soften the starts and stops.

Finally, click on your “chat bubble” layer, and remove the dot masks (Masks 1/2/3 in my comp).

Dots all animated

So that’s it for animation! To use this in xcode, there are a few things to do. First of all, the image should be cropped to the boundaries of the button or view you want to place the image in. We’re planning on making this 124px square, so just right-click outside the canvas and change the composition settings to adjust. The last thing to do before rendering is trim the composition length. Place the playhead at 29 frames and hit “n”. This will move the end of your work area, and control what is rendered by After Effects.

Cropped composition, ready for rendering

To render the comp, select “Add to render queue..” under the Composition menu. This will opne the Render Queue, and you can set the output options for the composition. Click where it says “Lossless” next to “Output Module:”. In the dialog that opens, change the Format at the top to “PNG Sequence”, and the Video Output Channels to “RGB + Alpha”. Click OK and close this dialog. Back on the Render Queue, click where it says “Not Yet Specified” for the output destination. Choose where you want to save the file – it’s probably best to make a folder, since we’re about to generate 30 images. Also, since this icon is designed at 2x, make sure to add @2x to the end of the filename, so that Xcode recognizes the imported frames as 2x assets. Click Render and all the animation frames will export!

One good thing to keep in mind is to optimize the filesize of the PNG frames. I use an app called PNG Compressor to prepare batches of images.

Time to open up Xcode! Start a new project, and make a Single View Application. Name it Chat Indicator. Don’t worry about the company name etc, since this is just for demonstration purposes.

The first thing to do is import the animation frames to your project. Access the image library by clicking on “Images.xcassets” in your project explorer. To import the images, you can just drag and drop them onto the library pane. I recommend dragging the entire Animated Loader folder onto the library to retain the grouping, just for organization.

Animated loader frames imported to Xcode

At this point, I had to move my animation frames over to the 2x column, since I didn’t name them appropriately with @2x. If this situation happens to you, just drag the frames over to the correct spot.

Time to get to the fun stuff! Click on Main.storyboard to open the interface builder and start working on the main screen. The basis of our animated loading icon is going to be an image view. Drag an Image View from the Object Browser to the center of the canvas. Click on the Size Inspector and set the size of the Image View to 62px square. Recenter it in the canvas.

Image View added to Main storyboard

Toggle to the Attributes Inspector and set the Image property of the Image View to the first frame of the animation. Click on the Align button in the lower right corner of the Interface Builder window, and check the Horizontal and Vertical Center options. Click “Add 2 Constraints”. The button next to Align is Pin – click it now. Check “Aspect Ratio” and then add the constraint. Now, the icon will appear the proper size on all screens, and remain centered. If you want to really support all devices, it’s wise to use proper sized assets for each. For simplicity’s sake, we’re just using 2x here.

Image View constraints and placeholder image set

Now it’s time to start adding a bit of code to hook this thing up. Go ahead and close the Utilities panel if you need the space, and open your Assistant Editor. You should see the ViewController.swift code on the right side. Control-drag from the Image View in your storyboard to the code, on line 12, right under the class definition for the ViewController: class ViewController: UIViewController {

Once you drag the connection, a dialog will pop up asking you to name it. Make sure it’s set to create an Outlet, and name it “chatLoader”. Accept, and a property will be created, linking the Image View to your code.

chatLoader outlet created

Now that the property is created, we can start modifying that object through code. To turn this into an animation, we use a property of an Image View called animationImages. By default, this property is set to nil. If you change it to anything else, the image property will be ignored and the view will instead show the animationImages in sequence. The length of the animation is determined by another property called animationDuration.

To assign each animation frame to the animationImages property, we’ll simply loop through the frames and add them to the array. In the viewDidLoad function, under the super call, type: chatLoader.animationImages = [UIImage](). This will create an empty array of UIImage, and assign it to the animationImages property. We need to create this array before adding objects to it.

The only tricky part to this step is making the proper image names for each frame. The easiest way to do this requires us to import Foundation. Go to line 10 in your code, right under import UIKit type import Foundation.

Now, on line 21, after the line that sets up the empty array for the animationImages, we can start setting up the For loop. Here’s what the code looks like:

for var index = 0; index < 30; index++ {
    var frameName = String(format: "indicator_%05d", index)
    chatLoader.animationImages?.append(UIImage(named: frameName)!)
}

This code will just step through 30 times (from 0-29) and create a string for the image name. The string it creates starts with “indicator_” and a 5-digit integer based on the index. After creating the frameName, it appends the UIImage for that name to the animationImages array. When this loop completes, that property will contain all our frames in order.

A complete animation needs to have a duration set as well. This animation is a 1 second loop, so we’ll set the animationDuration to 1, and then start animating the ImageView.

chatLoader.animationDuration = 1
chatLoader.startAnimating()

That’s it!

Run the app, and you’ll see the chat icon animating away. You can even rotate the phone and it will move appropriately because of the constraints. There are a variety of ways to animate something like this, but frame-based animation is one of the simplest and quickest to implement. Plus if you happen to change the animation, all you have to do is update the image source files.

To show off your animation, it’s really easy to make a high quality presentation. You’ve already got the animation as an After Effects file, so you can just drop it into a something like our iPhone 6 Presentation Template. No need to take a screen-cap. All you have to do is render it, open it in Photoshop, and save it as a gif.

Hopefully you find some really interesting ways to use this technique. Let us know in the comments if you make something you’re proud of! If you’re a designer and looking to get into code, our learning section has some amazing resources, including Xcode for Designers, a course focused on helping UI Designers learn how to turn their designs into actual native apps in Xcode!

You can even snag 10% off any of the products mentioned in this exercise by using coupon code chatloader