4.
Springs
Written by Marin Todorov
Springs in UIKit provide more polish and aesthetics to view animations. Apple themselves use springs for a wide number of system animations as well as in their own applications. Springs are usually responsible for any bouncing views you see on screen, but in fiddling with the spring animation parameters you will see that this API allows you to create a variety of pleasing animations.
So far, your animations have been fluid movements in a single direction. When you animated a view’s position, it was a straightforward movement from point A to point B, like so:
In this chapter you’ll learn how to create more complex animations, which move views as if they were attached to a spring, as demonstrated below:
If you took the basic animation from point A to point B and added a bit of springiness to it, the motion of the animation would follow a path indicated by the red arrows below:
The view heads from point A to point B, but overshoots point B by a small amount. The view then heads back to point B and overshoots by a little less this time. This back-and-forth oscillation repeats until the view has come to rest at point B.
It’s a nice effect; it adds a snappy, real-world feel to your animations. This chapter will show you how to use this effect to add a little bit of playfulness to your UI.
Spring animations
You’ll continue on with the project from the previous chapter; if you didn’t complete the exercises in Chapter 3 (including the challenge at the end of the chapter), then grab the starter project from the Resources folder for Chapter 4 and start from there.
Build and run your project; you should see the views on screen (except the Log In button) animate as soon as the app opens like so:
Your job is to take care of the last non-animated element on this screen: the Log In button.
Open ViewController.swift and add the following code to the bottom of viewWillAppear()
:
loginButton.center.y += 30.0
loginButton.alpha = 0.0
Just as you did in the previous chapter, you set the start position of the button a bit lower on the y-axis and set its alpha value to zero so that it will start out as invisible.
Now move to viewDidAppear()
and add the following code:
UIView.animate(withDuration: 0.5, delay: 0.5,
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: [], animations: {
self.loginButton.center.y -= 30.0
self.loginButton.alpha = 1.0
}, completion: nil)
There are two key points in this piece of code.
First, you’ve animated two different properties at the same time! That was easier than you thought, right?
Second, you used a new animation method for the first time: animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)
. Saying that method name too quickly just might injure your tongue!
The previous method looks much like the ones you used in the previous chapter of the book, but it sports a couple of new parameters:
-
usingSpringWithDamping
: This controls the amount of damping, or reduction, applied to the animation as it approaches its final state. This parameter accepts values between0.0
and1.0
. Values closer to0.0
create a bouncier animation, while values closer to1.0
create a stiff-looking effect. You can think of this value as the “stiffness” of the spring. -
initialSpringVelocity
: This controls the initial velocity of the animation. A value of1.0
sets the initial velocity of the animation to cover the total distance in the span of one second. Bigger and smaller values will cause the animation to have more or less velocity, and will affect how the spring settles. Note however that the initial velocity is soon amended by the spring calculation, and the animation will always finish by the end ofduration
.
Build and run your project; check out how the button moves now:
Since your animation has an initial velocity of 0.0
and a neutral damping of 0.5
, the animation doesn’t look very eye-catching.
You should be able to dress up this animation a little by trying some different values for the velocity and damping.
Change the duration to 3.0
and the damping to 0.1
. This is just to let you observe the effect of your changes in slow motion instead of at normal speed.
Build and run your project again; note how the opacity of the button changes as it moves up. This is because the spring behavior affects all properties you animate; in your case, this affects both the vertical position of the button and its alpha value.
Now set initialSpringVelocity
to 1.0
and build and run your project again:
You’ll notice that the button bounces a bit more when it animates and moves beyond the password field; this is because it has more momentum at the beginning of its movement.
Play around with some different values for damping and velocity until you understand how changes in these parameters affect the look and feel of your animation.
When you’re done, set the values for the velocity and damping back to their original values, like so:
UIView.animate(withDuration: 0.5, delay: 0.5, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: [], animations: {
self.loginButton.center.y -= 30.0
self.loginButton.alpha = 1.0
}, completion: nil)
Animating user interactions
You don’t have to limit your spring animations to the initial placement of your views. In fact, animating views in response to user input can really make your interface come alive. In this section you’ll animate the Log In button in response to a tap.
Add the following code to login()
:
UIView.animate(withDuration: 1.5, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 0.0, options: [], animations: {
self.loginButton.bounds.size.width += 80.0
}, completion: nil)
The above animation increases the button’s width by 80
points over a duration of a second and a half. The button will bounce around a fair bit as well since the damping is set to just 0.2
. Increasing the bounds grows the frame on its left and right sides.
Build and run your project; tap the button to see your animation in action:
The button grows and bounces in a blobby fashion when you tap it; it’s a neat way to provide tap feedback to the user.
Next you’ll combine this animation with a few more spring movements to really bring the button to life.
Add the following code to the end of login()
:
UIView.animate(withDuration: 0.33, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: [], animations: {
self.loginButton.center.y += 60.0
}, completion: nil)
The above animation moves the button 60
points down when tapped. Notice that the duration for this animation is much shorter than the one that animates the button width.
This is intentional, since the desired effect is to make the button jump away from the tap and bounce a bit once it’s settled into its new vertical position.
Build and run your project; tap the button and see how it moves in response to your touch this time:
That looks really nice — but you’re quickly becoming an animation master and you know that you can do even better!
Another great way of providing user feedback is through color change. You’ll tint the button as it moves by animating the backgroundColor
property of the button.
Add the following code to the last animation you added, inside the animations
closure expression:
self.loginButton.backgroundColor =
UIColor(red: 0.85, green: 0.83, blue: 0.45, alpha: 1.0)
Build and run your project again; you’ll see the button move, change shape and change color, all at the same time:
There’s one last bit of feedback to add here: an activity indicator. The Log In button is supposed to start a user authentication activity over the network, so it would be nice to show an activity indicator to the user to let them know that there’s an action in progress.
Scroll up and have a look at viewDidLoad()
and find the existing code for the progress indicator. spinner
contains an instance of UIActivityIndicatorView
that’s all ready for your use. You haven’t seen it on the screen yet because its alpha is set to 0.0
.
Head back to login()
and add the following code to the last animations
closure expression:
self.spinner.center = CGPoint(
x: 40.0,
y: self.loginButton.frame.size.height/2
)
self.spinner.alpha = 1.0
This animation moves the spinner slightly to the left and fades it in. This should be enough to attract the user’s attention and let them know their request is being processed.
Build and run your project; check out the final version of your spiffy new animation:
Take a moment to reflect on what you’ve accomplished here. You’ve added three simultaneous animations to the button view to make it grow in width, move down the screen, and change color.
You’ve also animated and faded in an activity spinner, which is itself a subview of the button view.
All animations are combined automatically by UIKit and run flawlessly to create one fluid visual effect.
There’s no need for you to worry about the implementation details of your animations; you can instead focus on designing great animations and wowing your users thanks to UIKit!
Key Points
- You can create visual feedback for user interaction by creating animations in response to the user’s actions.
- You create spring animations in a very similar manner to “standard” animations — the additional parameters are the spring damping and initial velocity.
- Combining various animations (with springs or without) creates rich visual experiences.
Challenges
Challenge 1: Convert text field animations to spring-animations
The spring animation APIs in UIKit are quite similar in usage to their standard animation counterparts. Thus it shouldn’t be much of a problem for you to convert the animations you have running on the username
and password
fields to spring animations.
To complete this challenge you will need to do the following:
-
Add the
usingSpringWithDamping
andinitialSpringVelocity
parameters to the animation for the username field. Use0.0
for the spring initial velocity. Try out0.2
,0.6
and0.9
for the spring damping and choose the value that looks most like a pleasant and subtle spring effect to you. -
Repeat the same for the
password
field animation using the damping and velocity of your choice.
By this point in the book you’ve gained a solid foundation of spring animation. The more you play with this type of animation, and the more you experiment with different combinations of damping and velocity, the more comfortable you’ll be designing the perfect spring animation for the views in your own apps.
Are you ready to spring into the next chapter? In Chapter 5, you’ll learn about the next type of animation in UIKit: transitions.