isActive = true vs. NSLayoutConstraint.activate
Tags: swift, xcode, ios
Published: 2019-01-31 20:16:53

---
title: isActive = true vs. NSLayoutConstraint.activate
published: true
tags: swift, xcode, ios
canonical_url: https://zeitschlag.net/isactive-true-vs-nslayoutconstraint-active/
---

The whole UI of the app, I helped to develop, is written in code. No Storyboards, no XIBs, just Swift. Someone made this decision looooong ago. Nevertheless, we're using AutoLayout, just like [every cool kid should](https://twitter.com/_Caro_N/status/1017364995481440257) do these days.

Typically, our code looks like this:

```
self.titleLabel.topAnchor.constraint(equalTo: self.titleView.opAnchor, constant: 16).isActive = true
```

Now imagine, that there's more than one constraint, take this for example:

```
contentWrapper.leftAnchor.constraint(equalTo: swipeContentView.leftAnchor, constant: 8).isActive = true
contentWrapper.rightAnchor.constraint(equalTo: swipeContentView.rightAnchor, constant: -8).isActive = true
contentWrapper.topAnchor.constraint(equalTo: swipeContentView.topAnchor, constant: 4).isActive = true
contentWrapper.bottomAnchor.constraint(equalTo: swipeContentView.bottomAnchor, constant: -4).isActive = true

imageView.topAnchor.constraint(equalTo: contentWrapper.topAnchor, constant: 12).isActive = true
imageView.leftAnchor.constraint(equalTo: contentWrapper.leftAnchor, constant: 12).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 120).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 90).isActive = true

titleContainerStackView.leftAnchor.constraint(equalTo: imageView.rightAnchor, constant: 12).isActive = true
titleContainerStackView.topAnchor.constraint(equalTo: contentWrapper.topAnchor, constant: 12).isActive = true
titleContainerStackView.rightAnchor.constraint(equalTo: contentWrapper.rightAnchor, constant: -12).isActive = true

stepper.translatesAutoresizingMaskIntoConstraints = false
stepper.leftAnchor.constraint(equalTo: contentWrapper.leftAnchor, constant: 12).isActive = true
stepper.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 9).isActive = true
stepper.widthAnchor.constraint(equalToConstant: 120).isActive = true
stepper.heightAnchor.constraint(equalToConstant: 32).isActive = true

shortDescriptionLabel.topAnchor.constraint(equalTo: titleContainerStackView.bottomAnchor, constant: 4).isActive = true
shortDescriptionLabel.leftAnchor.constraint(equalTo: imageView.rightAnchor, constant: 12).isActive = true
shortDescriptionLabel.rightAnchor.constraint(equalTo:contentWrapper.rightAnchor, constant: -12).isActive = true

bottomStackView.bottomAnchor.constraint(equalTo: contentWrapper.bottomAnchor, constant: 0).isActive = true
bottomStackView.leftAnchor.constraint(equalTo: contentWrapper.leftAnchor, constant: 12).isActive = true
bottomStackView.rightAnchor.constraint(equalTo: contentWrapper.rightAnchor, constant: -12).isActive = true
```

I see two issues with this approach:

- Although it might be very comfortable for you, while you write this code, to do two things at a time — creating a constraint and activating them — it's something, your future-self will hate you for.
- There's the risk of forgetting to add a `.isActive = true`, at least this happened to me a few minutes ago.

There's a better way than activating each constraint individually: It's called [`NSLayoutConstraint.activate()`](https://developer.apple.com/documentation/uikit/nslayoutconstraint/1526955-activate):

> This convenience method provides an easy way to activate a set of constraints with one call. The effect of this method is the same as setting the isActive property of each constraint to true. Typically, using this method is more efficient than activating each constraint individually. — [Source](https://developer.apple.com/documentation/uikit/nslayoutconstraint/1526955-activate)

The last couple of hours, I've been working on a screen, that features two `UILabel` and a `UICollectionView`. In the end it should look similar to this:

![Bildschirmfoto-2018-07-17-um-12.40.42](https://zeitschlag.net/content/images/2018/07/Bildschirmfoto-2018-07-17-um-12.40.42.png)

So I added all the elements and constraints and pressed `CMD+R`. But it didn't work. The numbers weren't visible, but at the same time, there were no unsatisfiable constraints. I doublechecked the constraints, and they looked fine. After some time, I found out, that there was a `isActive = true` missing.

After fixing this and `CMD+R`-ing again, I applied a little refactoring using [`NSLayoutConstraint.activate()`](https://developer.apple.com/documentation/uikit/nslayoutconstraint/1526955-activate) right away. Now this code looks similar to this:

```
let constraints = [
    self.titleLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 16),
    self.titleLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16),
    self.view.trailingAnchor.constraint(equalTo: self.titleLabel.trailingAnchor, constant: 16),
	// ...
]

NSLayoutConstraint.activate(constraints)
```

Much better. If you were very strict, you could argue, that I should put each constraint into a constant before adding it to the `constraints`-array.

I'm pretty sure, that using `NSLayoutConstraint.activate()` in the first place would have saved me some time. When I will add some more constraints in the future, I don't have to think about activating them. If I forgot the `,`, the compiler will complain. Future-Nathan will be thankful for this.

Hopefully.

Thank you for reading this.