Skip to Content
Course content

188: Auto Layout Programmatically

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Why are my constraints being ignored or causing conflicts the moment I run the app?

This is the "rite of passage" for everyone learning programmatic layout. You spend twenty minutes perfectly defining your anchors, run the app, and your view is either stuck at (0,0) with a size of 0x0, or your console is screaming about conflicting constraints.

The culprit is almost always translatesAutoresizingMaskIntoConstraints. By default, views created in code have this property set to true. This is a leftover from the old days of "springs and struts" (Autoresizing Masks). When it's true, iOS automatically creates a set of constraints that mimic the old system. If you then add your own Auto Layout constraints, they clash with those auto-generated ones.

I've lost count of how many times I forgot this. Just remember: if you're doing Auto Layout in code, you must set this to false before adding the view to the hierarchy.

let profileImageView = UIImageView()
profileImageView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(profileImageView)

What's the cleanest way to actually define the constraints?

You might see some older tutorials using NSLayoutConstraint(item:attribute:relatedBy:toItem:attribute:multiplier:constant:). Please, for your own sanity, ignore that. It's verbose, hard to read, and a nightmare to debug.

Use Layout Anchors. They make the code read much more like a sentence. Let's say we're building a simple profile header where we want an image centered in the screen and a name label pinned right below it. It looks like this:

// Center the image
NSLayoutConstraint.activate([
    profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    profileImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    profileImageView.widthAnchor.constraint(equalToConstant: 100),
    profileImageView.heightAnchor.constraint(equalToConstant: 100)
])

// Pin the label to the bottom of the image
NSLayoutConstraint.activate([
    nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16),
    nameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])

Notice how topAnchor.constraint(equalTo: ...) clearly describes the relationship. It's intuitive, and the compiler will catch it if you try to constrain a topAnchor (Y-axis) to a leadingAnchor (X-axis).

Do I really need to call activate() on every single constraint?

You could call .isActive = true on every single line, but that's tedious and actually slightly worse for performance. Every time you activate a constraint individually, the system potentially triggers a layout pass to re-calculate the entire UI.

The professional way to do it is using NSLayoutConstraint.activate([]). This method takes an array of constraints and activates them all in one single batch. It's cleaner, faster, and keeps your layout logic grouped together. I usually group my constraints by the view they belong to, so I can easily find where the "image layout" ends and the "label layout" begins.




📋 Practical Task

Build a Centered Profile Card

Create a UIView subclass called ProfileCardView. Inside this view, programmatically add an UIImageView and a UILabel. Your goal is to achieve the following layout using Auto Layout anchors:

  • The UIImageView should be a 60x60 square, centered horizontally in the card, and pinned to the top of the card with a 20pt margin.
  • The UILabel should be centered horizontally, pinned to the bottom of the image with a 10pt margin, and pinned to the bottom of the card with a 20pt margin.
  • Ensure all views have translatesAutoresizingMaskIntoConstraints set to false.

Test your implementation by adding the ProfileCardView to a View Controller and giving the card a background color so you can see the constraints working.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.