In
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var logoView: UIImageView!
    @IBOutlet weak var superview: UIView!

    @IBOutlet weak var usernameLabel: UILabel!
    @IBOutlet weak var usernameTextBox: UITextField!

    @IBOutlet weak var passwordLabel: UILabel!
    @IBOutlet weak var passwordTextBox: UITextField!

    @IBOutlet weak var loginButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        createConstraints()
    }

    func createConstraints() {

        logoView.translatesAutoresizingMaskIntoConstraints = false

        let widthOfLogoView = NSLayoutConstraint(item: logoView,
                                                 attribute: .width,
                                                 relatedBy: .equal,
                                                 toItem: nil,
                                                 attribute: .notAnAttribute,
                                                 multiplier: 1.0,
                                                 constant: 128)

        let heightOfLogoView = NSLayoutConstraint(item: logoView,
                                                 attribute: .height,
                                                 relatedBy: .equal,
                                                 toItem: nil,
                                                 attribute: .notAnAttribute,
                                                 multiplier: 1.0,
                                                 constant: 128)

        let centerXPosition = NSLayoutConstraint(item: logoView,
                                                  attribute: .centerX,
                                                  relatedBy: .equal,
                                                  toItem: superview,
                                                  attribute: .centerX,
                                                  multiplier: 1.0,
                                                  constant: 0.0)

        let centerYPosition = NSLayoutConstraint(item: logoView,
                                                 attribute: .centerY,
                                                 relatedBy: .equal,
                                                 toItem: superview,
                                                 attribute: .centerY,
                                                 multiplier: 1.0,
                                                 constant: -140.0)

        superview.addConstraints([widthOfLogoView, heightOfLogoView, centerXPosition, centerYPosition])

        let widthOfUsernameLabel = NSLayoutConstraint(item: usernameLabel,
                                                     attribute: .width,
                                                     relatedBy: .equal,
                                                     toItem: nil,
                                                     attribute: .notAnAttribute,
                                                     multiplier: 1.0,
                                                     constant: 240)

        let widthOfUsernameTextBox = NSLayoutConstraint(item: usernameTextBox,
                                                      attribute: .width,
                                                      relatedBy: .equal,
                                                      toItem: nil,
                                                      attribute: .notAnAttribute,
                                                      multiplier: 1.0,
                                                      constant: 240)

        let widthOfPasswordLabel = NSLayoutConstraint(item: passwordLabel,
                                                      attribute: .width,
                                                      relatedBy: .equal,
                                                      toItem: nil,
                                                      attribute: .notAnAttribute,
                                                      multiplier: 1.0,
                                                      constant: 240)

        let widthOfPasswordTextBox = NSLayoutConstraint(item: passwordTextBox,
                                                        attribute: .width,
                                                        relatedBy: .equal,
                                                        toItem: nil,
                                                        attribute: .notAnAttribute,
                                                        multiplier: 1.0,
                                                        constant: 240)

        let widthOfLoginButton = NSLayoutConstraint(item: loginButton,
                                                        attribute: .width,
                                                        relatedBy: .equal,
                                                        toItem: nil,
                                                        attribute: .notAnAttribute,
                                                        multiplier: 1.0,
                                                        constant: 240)

        let YPositionOfUsernameLabel = NSLayoutConstraint(item: usernameLabel,
                                                          attribute: .top,
                                                          relatedBy: .equal,
                                                          toItem: logoView,
                                                          attribute: .bottom,
                                                          multiplier: 1.0,
                                                          constant: 30)

        let YPositionOfUsernameTextBox = NSLayoutConstraint(item: usernameTextBox,
                                                          attribute: .top,
                                                          relatedBy: .equal,
                                                          toItem: usernameLabel,
                                                          attribute: .bottom,
                                                          multiplier: 1.0,
                                                          constant: 0.0)

        let YPositionOfPasswordLabel = NSLayoutConstraint(item: passwordLabel,
                                                          attribute: .top,
                                                          relatedBy: .equal,
                                                          toItem: usernameTextBox,
                                                          attribute: .bottom,
                                                          multiplier: 1.0,
                                                          constant: 30.0)

        let YPositionOfPasswordTextBox = NSLayoutConstraint(item: passwordTextBox,
                                                          attribute: .top,
                                                          relatedBy: .equal,
                                                          toItem: passwordLabel,
                                                          attribute: .bottom,
                                                          multiplier: 1.0,
                                                          constant: 0.0)

        let YPositionOfLoginButton = NSLayoutConstraint(item: loginButton,
                                                            attribute: .top,
                                                            relatedBy: .equal,
                                                            toItem: passwordTextBox,
                                                            attribute: .bottom,
                                                            multiplier: 1.0,
                                                            constant: 30.0)

        let XPositionOfUsernameLabel = NSLayoutConstraint(item: usernameLabel,
                                                 attribute: .centerX,
                                                 relatedBy: .equal,
                                                 toItem: superview,
                                                 attribute: .centerX,
                                                 multiplier: 1.0,
                                                 constant: 0.0)

        let XPositionOfUsernameTextBox = NSLayoutConstraint(item: usernameTextBox,
                                                          attribute: .centerX,
                                                          relatedBy: .equal,
                                                          toItem: superview,
                                                          attribute: .centerX,
                                                          multiplier: 1.0,
                                                          constant: 0.0)

        let XPositionOfPasswordLabel = NSLayoutConstraint(item: passwordLabel,
                                                          attribute: .centerX,
                                                          relatedBy: .equal,
                                                          toItem: superview,
                                                          attribute: .centerX,
                                                          multiplier: 1.0,
                                                          constant: 0.0)

        let XPositionOfPasswordTextBox = NSLayoutConstraint(item: passwordTextBox,
                                                          attribute: .centerX,
                                                          relatedBy: .equal,
                                                          toItem: superview,
                                                          attribute: .centerX,
                                                          multiplier: 1.0,
                                                          constant: 0.0)

        let XPositionOfLoginButton = NSLayoutConstraint(item: loginButton,
                                                          attribute: .centerX,
                                                          relatedBy: .equal,
                                                          toItem: superview,
                                                          attribute: .centerX,
                                                          multiplier: 1.0,
                                                          constant: 0.0)

        usernameLabel.translatesAutoresizingMaskIntoConstraints = false
        usernameTextBox.translatesAutoresizingMaskIntoConstraints = false
        passwordLabel.translatesAutoresizingMaskIntoConstraints = false
        passwordTextBox.translatesAutoresizingMaskIntoConstraints = false
        loginButton.translatesAutoresizingMaskIntoConstraints = false

        superview.addConstraints([XPositionOfUsernameTextBox, XPositionOfUsernameLabel, XPositionOfPasswordLabel, XPositionOfPasswordTextBox, XPositionOfLoginButton])
        superview.addConstraints([YPositionOfUsernameTextBox, YPositionOfUsernameLabel, YPositionOfPasswordLabel, YPositionOfPasswordTextBox, YPositionOfLoginButton])
        superview.addConstraints([widthOfUsernameLabel, widthOfUsernameTextBox, widthOfPasswordLabel,widthOfPasswordTextBox ,widthOfLoginButton])

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

You might encounter some cases where you need to create and manipulate constraints directly in code. In this case there are much less tools involved and also we covered the behavior of constraints in the Interface Builder part of the exercise so this part will most likely end up smaller than the Interface Builder part. However , there are some additional things you need to know about.

Here’s what I’ll focus your attention on:

First of we’ll take a look at the required objects and the required functions for creating constraints in code. After that we’ll take a look at how to adjust constraints.

We’ll focus first on how to create Constraints in Code.

Creating Constraints in Code

Just like with the constraints we dealt with in Interface Builder, there are a couple of things that need to be set in order for the constraints to work properly. The concept is exactly the same so a valid set of constraints defines the size of the view as well as the position of the view. So just like the rules we had before ein the interface builder. We need to set the width, the height and the X and Y Coordinates of the view.

So we need to create some variables that contain our constraints. The types of constraints may vary from situation to situation, but let’s just say we want to replicate the logo example by creating the constraints in code this time.

A little bit of work is needed to set up the testing environment in this case. Let’s just remove all our constraints we added in the interface builder and remove all the outlets for constraints. We’re now at a starting point where everything should be like we just pulled out the view of the object library and put it on the canvas.

Required Objects

Now we need to create an outlet for the view from the storyboard to the code file. Of course you could also create the view inside of the code file and ignore the interface builder completely but I’ll focus on that in another module since there is a lot to cover here too. This is the first object that is required to create constraints in code. I’ll refer to this as the „imageView“ in this section because we’re later going to put an image into this view as it should display our logo.

The second object that is needed is the „superview“, meaning the other view that our „imageView“ is nested inside. This is necessary because swift needs to know the two objects that the constraints exist between. You can never connect a constraint to nothing, it always needs a first and a second object to work with. There are some special cases where the second object is not interesting for us for example if we set the width or the height of a view, but I’ll cover that later. Just know that there are some exceptions to this rule.

The last object we need is the constraint itself. Constraints are created as a NSLayoutConstraint object which is part of the UIKit. You can just create variables of that type and save the constraints inside of there. What’t more interesting though is the constructor you’ll need.

Required Functions

I’ll classify this as a function since a constructor is basically a function call that initializes the state of the object. There are just two versions for the NSLayoutConstraint. The first one is empty and creates an empty constraint which basically does nothing at all. The other one is the interesting one. Let’s look at the required arguments for this constructor call:

First up we have an Item. Then we have an attribute, we have relatedBy we have a toItem another attribute and all of this is followed by the multiplier as well as a constant.

If you payed attention in the theory part, you might notice something right here. That graphic I showed you that specified the anatomy of a constraint basically has exactly the same structure that the arguments in this constructor call have. This makes it quite easy to understand what is happening here and this is the reason I taught you the anatomy of a constraint first.

Firstly we select and item. This is the object that should be aligned or adjusted based on the constraint. The attribute specifies which value needs to be set. Remember this could be position or size related or even both.

Then there is the relation. Most of the time you’ll be looking at equals, but for example if you want something to expand only to a certain width, you could use a more-or-equal / less-orequal relation.

Then there is the toItem which is the item the value will be taken from and the attribute which acts just like the attribute on the first item.

Lastly we have the multiplier and then the constant. Both of them should be familiar to you from the Interface Builder screen.

NotAnAttribute

You might have noticed, that there are some cases in which you don’t need all the parameters in the function. Especially when setting the width or height of a view, you don’t need to have a superview, because t just affect one view. But the arguments in the function are required, so what can we do?

Apple has a clever way of dealing with this. If you’re familiar with optionals in swift, you might know where this is going. Let’s just say we want to set the height of a view with the name of „view“. We would enter „view“ as the item and „Height“ as a parameter. In our case let’s just say we use the equals relation.

Now what about the toItem and the attribute of the toItem? Easy. As our toItem, just set „nil“. Now the interesting part is the attribute. This is where we will enter „notAnAttribute“. This is a case of an enum that is defined as 0, meaning this will not affect our layout equation in any way. We can now use the constant to set the height of our view.

Sounds a little bit weird at first, but that’s just something you need to keep in mind to work with it.

So you now know all the attributes, items, equations and everything in between. But how do we tell this to the auto-layout system? This is hard to explain using slides, so we’re just going to jump right into Xcode to get this working.

Adjusting Constraints

Sample of the most common Functions

You probably noticed that all of this seems a bit complex and confusing and the especially the creation of constraints in code is very verbose. That’s why I created some bonus content about a Library that can help you manage constraints with more ease.

Ask Anything!

Do you have any questions? Ask them! I'll answer via Email as soon as I read it.

Not readable? Change text. captcha txt
0