In this tutorial, we’ll be animating our UI Views in various ways in the iOS Application.
iOS UIView Animations
Animations are a vital component in building beautiful UIs.
Following are some of the basic properties of a view that can be animated:
- center
- alpha
- frame
- bounds
- transform
- backgroundColor
- contentStretch
The syntaxes for UIView Animations are:
UIView.animate(withDuration:, animations:)
UIView.animate(withDuration:, delay:, animations:)
UIView.animate(withDuration:, delay:, options:, animations:)
UIView.animate(withDuration:, delay:, options:, animations:, completion:)
UIView.animate(withDuration: 5.0, animations: {
self.myView.alpha = 0
print("animations")
})
With Delay:
UIView.animate(withDuration: 5.0, delay: 2.0, animations: {
self.myView.alpha = 0
print("animations")
})
Notice that there is a two second delay:
With Options
UIView.animate(withDuration: 5.0, delay: 2.0, options: [.autoreverse], animations: {
self.myView.alpha = 0
print("animations")
})
There are plenty of options available that we will see later in this tutorial. The above one auto-reverses the animation once before vanishing it off.
With completion
A Completion handler closure gets called when the animation is completed.
We can add a completion handler as shown below:
UIView.animate(withDuration: 5.0, animations: {
self.myView.alpha = 0
print("animations")
},completion:
{finished in
print("Is finished? \(finished)")
UIView.animate(withDuration: 1.0, animations:{
self.myView.alpha = 0.5
},completion: nil)
})
In this, we’ve chained another animation when the first is completed.
A completion is a trailing closure. We can enhance the readability of the code by calling the completion outside function as shown below:
UIView.animate(withDuration: 5.0, animations: {
self.myView.alpha = 0
print("animations")
}){finished in
print("Is finished? \(finished)")
UIView.animate(withDuration: 1.0, animations:{
self.myView.alpha = 0.5
})
}
Note: finished is a boolean.
UIView.animateWithDuration(5.0, animations: {
println("animations")
}, completion: { finished in
println("completion")
})
This is because no UIView was animated.
You must call a view and animate it in the animation block.
Let’s open up our Main.storyboard in our new XCode Project.
Following is the UI we’ve created for the next three basic animations that we’ll perform:
Create an IBAction in the ViewController.swift for each of the other Buttons similarly.
Animating Color
@IBAction func animateColor(_ sender: Any) {
UIView.animate(withDuration: 1, animations: {
self.myView.backgroundColor = UIColor.black
}, completion: nil)
}
Animate Movement
Here we change the position of the view using the frame origin as the reference.
A negative in x-direction means it goes to the left.
A negative in the y-direction means it goes to the top.
@IBAction func animateMovement(_ sender: Any) {
UIView.animate(withDuration: 1, animations: {
self.myView.frame.origin.x -= 40
}, completion: nil)
}
Animate Size
Here we change the frame size width and height.
@IBAction func animateSize(_ sender: Any) {
UIView.animate(withDuration: 1, animations: {
self.myView.frame.size.width += 40
self.myView.frame.size.height += 10
}){ finished in
UIView.animate(withDuration: 1, animations: {
self.myView.frame.size.width -= 40
self.myView.frame.size.height -= 10
})
}
}
Animate Together
Here we’ll animate the size, color and position of the View together.
@IBAction func animateAllTogether(_ sender: Any) {
if(animationRunning){
self.myView.layer.removeAllAnimations()
animationRunning = !animationRunning
}
else{
animationRunning = !animationRunning
UIView.animate(withDuration: 1, animations: {
self.myView.backgroundColor = UIColor.green
self.myView.frame.size.width += 50
self.myView.frame.size.height += 20
self.myView.center.x += 20
}) { _ in
UIView.animate(withDuration: 1, delay: 0.25, options: [.autoreverse, .repeat], animations: {
self.myView.frame.origin.y -= 20
})
}
}
}
animateRunning
is a boolean variable that is used to toggle the UIView Animation.
To stop the animation we do : self.myView.layer.removeAllAnimations()
.
We’ve set the options to auto-reverse and repeat forever.
The output of the above 4 basic animations is given below:
Next, we’ll look at Transform Animations and use the various options.
Transform Animations
We can transform the scale, rotate the views to show animations.
Following is the setup from the storyboard:
In the above storyboard, we’ve linked all the 4 buttons to the same IBAction function. The same function would be triggered when any of these buttons is clicked. We can set a button tag to identify the buttons from each other.
There are 4 main types of animation curves:
- curveEaseIn
- curveEaseOut
- curveEaseInOut
- curveLinear
Note: They are called curves since their animation graphs are curves!
To Transform animations we do:
self.optionsView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1.0, delay: 0.0, options: [.curveEaseIn], animations: {
self.optionsView.transform = .identity
})
CGAffineTransform
sets the intial scale.
self.optionsView.transform = .identity
transforms the view to it’s original scale.
We can set each of the options in their respective button tags as shown below:
The output of the application in action for the above transform animation is given below:
Spring Animations
Spring Animations behave like real-life springs. With their damping velocity and elasticity, they make a cool animation.
Spring Animations can be set by adding the following syntax for the UIView Animations animate
function.
UIView.animate(withDuration: 1, delay:, usingSpringWithDamping:, initialSpringVelocity:, options: [], animations: , completion:)
usingSpringWithDamping
requires a number between 0 and 1. It represents the damping ratio. The higher the number the springier the animation will be.
Higher the intialSpringVelocity, higher the intial momentum.
Again we’re creating a StackView with 4 Buttons for different use cases in our Main.storyboard:
The function springAnimationWithOptions is triggered everytime when any of the buttons is clicked:
@IBAction func springAnimationWithOptions(_ sender: UIButton!) {
if(sender.tag == 1)
{
self.optionsView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
else if(sender.tag == 2)
{
self.optionsView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
else if(sender.tag == 3)
{
self.optionsView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
else if(sender.tag == 4)
{
self.optionsView.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.8, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
}
Transform Animation – Translate, Scale, Rotate
We can scale translate and rotate in the following way:
let translate = CGAffineTransform(translationX: 120, y: 120)
let rotate = CGAffineTransform(rotationAngle: 360)
let scale = CGAffineTransform(scaleX: 2, y: 2)
We can also chain together each of these by using the concatenating method:
self.view.transform = translate.concatenating(rotate)
Our Main.storyboard again hooks the 4 buttons for the use cases to a common IBAction button click function:
The code for the STRAnimationWithOptions function is given below:
@IBAction func STRAnimationWithOptions(_ sender: UIButton!) {
if(sender.tag == 1)
{
let scale = CGAffineTransform(scaleX: 2, y: 2)
self.optionsView.transform = scale
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
else if(sender.tag == 2)
{
let translate = CGAffineTransform(translationX: -120, y: -120)
self.optionsView.transform = translate
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
else if(sender.tag == 3)
{
let rotate = CGAffineTransform(rotationAngle: 360)
self.optionsView.transform = rotate
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut, animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
else if(sender.tag == 4)
{
let rotate = CGAffineTransform(rotationAngle: 360)
let translate = CGAffineTransform(translationX: -120, y: -120)
let scale = CGAffineTransform(scaleX: 2, y: 2)
self.optionsView.transform = rotate.concatenating(translate).concatenating(scale)
UIView.animate(withDuration: 3, delay: 0,usingSpringWithDamping: 0.8,initialSpringVelocity: 0.5, options: [.autoreverse,.curveEaseInOut], animations: {
self.optionsView.transform = .identity
}, completion: nil)
}
}
In the last one, we’ve added spring animation as well. Check out the output of the Scale Rotate Translate Transform Animations.
Transition Options
Besides the curved animation option discussed above there are a few more.
To create transition animations we do the following in Swift:
UIView .transition(with: self.myTextField, duration: 4, options: .transitionCrossDissolve,
animations: {
self.myTextField.textColor = UIColor.red
})
Let’s see some of the important transition options by example.
First we need to set up the last part of our ViewController in the Main.storyboard:
We’ve created a UITextField and linked it to the ViewController.swift along with the three buttons.
The code for the transitionAnimationWithOptions function is given below:
@IBAction func transitionAnimationWithOptions(_ sender: UIButton!) {
if(sender.tag == 1)
{
UIView .transition(with: self.myTextField, duration: 4, options: .transitionCrossDissolve,
animations: {
self.myTextField.textColor = UIColor.red
}){finished in
self.myTextField.textColor = UIColor.white
}
}
else if(sender.tag == 2)
{
UIView .transition(with: self.myTextField, duration: 4, options: .transitionFlipFromRight,
animations: {
self.myTextField.textColor = UIColor.red
}){finished in
self.myTextField.textColor = UIColor.white
}
}
else if(sender.tag == 3)
{
UIView .transition(with: self.myTextField, duration: 4, options: .transitionCurlUp,
animations: {
self.myTextField.textColor = UIColor.red
})
}
}
The output of the above application in action is given below:
Wow, that’s the best for the last!
This brings an end to this tutorial. You can download the full XCode project with all the animations from the link below: