How to Animate Auto Layout Constraints

Make it look smooth and nice

Image for post
Image for post
Photo by Hal Gatewood on Unsplash

Animating constraints is one of those things that I’ve heard are tricky. Activate and reactivate constraints? You can do it! Just read on for the details.

Difficulty: Beginner | Easy | Normal | Challenging

The task

I’m going to create an attractive green button, and let it move around the screen according to it’s constraints.

Image for post
Image for post

I’ve set up the button (with fun constraints) in loadView(). Now I’ve set up this project in Playgrounds. This means that you’ll need import PlaygroundSupport and since I’m calling my View Controller myViewController (because I’m excellent at naming) I’ll need PlaygroundPage.current.liveView = MyViewController().

At the bottom of this page is the working Playground code — skip ahead to there if you choose not to have the rather excellent

Setting properties for the constraints

I’m going to put 4 constraints around my UIButton — these are going to define the height, width, XConstraint and YConstraint so effectively we are setting the size, X and Y position of the UIButton.

var buttWidthConstraint: NSLayoutConstraint!
var buttHeightConstraint: NSLayoutConstraint!
var buttXConstraint: NSLayoutConstraint!
var buttYConstraint: NSLayoutConstraint!

Setting the initial constraints

Assuming we have correctly set up the UIButton (we have…look at the full code below) we will set up the constraints shown below:

let buttWidthConstraint = myButt.widthAnchor.constraint(equalToConstant: 100)
let buttHeightContraint = myButt.heightAnchor.constraint(equalToConstant: 100)
let buttXConstraint = myButt.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
let buttYConstaint = myButt.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)

of course these need to be activated

NSLayoutConstraint.activate([
buttXConstraint,
buttYConstraint,
buttWidthConstraint,
buttHeightConstraint
])

and then set them above for the

self.buttXConstraint = buttXConstraint
self.buttYConstraint = buttYConstaint
self.buttWidthConstraint = buttWidthConstraint
self.buttHeightConstraint = buttHeightConstraint

Changing and animating the constraints

There are two types of constraint here — one that we will set with a constant (the buttHeightConstraint), and one set as an equalTo: relationship with the view’s center.

Setting to a constant

Step 1: Deactivate the constraint

NSLayoutConstraint.deactivate([
self.buttHeightConstraint
])

Step 2: Set the constant

Because the height doesn’t automatically revert to zero, we don’t need to set up a new constraint but can adjust the existing constraint — just use this one:

if self.buttHeightConstraint.constant == 100 {
self.buttHeightConstraint.constant = 39
}
else {
self.buttHeightConstraint.constant = 100
}

Step 3: Activate the constraint

NSLayoutConstraint.activate([
self.buttHeightConstraint
])

Step 4: Animate the change

Which can then be animated requesting an instant update through layoutIfNeeded():

UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}

Setting to a relationship

Step 1: Deactivate the constraint

NSLayoutConstraint.deactivate([
self.buttXConstraint
])

Step 2: Set a new constraint

Because the newButtXConstraint must always exist, we set up a newButtXConstraint to prevent the Button from zipping to the left hand side of the screen as it would not be constrained by any constraint.

var newButtXConstraint: NSLayoutConstraint
if self.buttXConstraint.constant == 100 {
newButtXConstraint = myButt.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
}
else {
newButtXConstraint = myButt.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 100)
}

Step 3: Activate the constraint

NSLayoutConstraint.activate([
self.buttHeightConstraint
])

Step 4: Animate the change

The X constraint for the button is changed to the new constraint. Which can then be animated requesting an instant update through layoutIfNeeded():

UIView.animate(withDuration: 0.5) {
self.buttXConstraint = newButtXConstraint,
self.view.layoutIfNeeded()
}

Job done-me-do

The full playground

Here is the full Playground! Copy and paste if you would like to.

Conclusion

You’ll need to deactivate constraints before animating them, but overall it should not be too difficult to create a nice little animation providing you have a good grasp of UIKit.

Questions

You can get in touch with me HERE; I’m usually available on Twitter so can get back to you…fast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store