home.


Tagged: ios-autolayout


Swift 3 and iOS: Add views programmatically with NSLayoutConstraint and AutoLayout

You can add a view programmatically in a fixed position easily enough:

self.edgesForExtendedLayout = [] // This ensures your view is below the navigation bar
...
let rect = CGRect(origin: CGPoint(x:0, y:0), size: CGSize(width:50, height:50))
var label = UILabel(frame: rect)
label.backgroundColor = UIColor.red
label.text = "label text"
self.view.addSubview(label)

However, if you use autolayout with NSLayoutConstraint then it’s the same as above but without the rect stuff, i.e. var label = UILabel(). You need to set translatesAutoresizingMaskIntoConstraints on the label to false to enable autolayout apparently. You then create layout constraints, for example:

NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal,
                   toItem: view, attribute: .centerX,
                   multiplier: 1.0, constant: 0.0)

The first line mentions the view you want it applied to, the attribute you want to constrain, and how it’s related to another. The second line says what we’re relating to, that relation’s attribute. We’ll ignore the last line for the moment.

So you’re saying “for the item label, relate its central x position to equals the central x position on view.” The below is saying “For the item label, relate its height to equal the height of view, for 95%.”

NSLayoutConstraint(item: label!, attribute: .height, relatedBy: .equal,
                   toItem: view, attribute: .height,
                   multiplier: 0.95, constant: 0.0)

Finally you add the contraints to your view: view.addConstraints([constraint1, constraint2, constraint3, constraint4]). The full example is:

 override func viewDidLoad() {
      super.viewDidLoad()

      self.edgesForExtendedLayout = []

      self.label = UILabel()
      self.label?.translatesAutoresizingMaskIntoConstraints = false
      self.label?.backgroundColor = UIColor.red
      self.label?.text = "label text"
      self.view.addSubview(self.label!)

      let horConstraint = NSLayoutConstraint(item: label!, attribute: .centerX, relatedBy: .equal,
                                             toItem: view, attribute: .centerX,
                                             multiplier: 1.0, constant: 0.0)
      let verConstraint = NSLayoutConstraint(item: label!, attribute: .centerY, relatedBy: .equal,
                                             toItem: view, attribute: .centerY,
                                             multiplier: 1.0, constant: 0.0)
      let widConstraint = NSLayoutConstraint(item: label!, attribute: .width, relatedBy: .equal,
                                             toItem: view, attribute: .width,
                                             multiplier: 0.95, constant: 0.0)
      let heiConstraint = NSLayoutConstraint(item: label!, attribute: .height, relatedBy: .equal,
                                             toItem: view, attribute: .height,
                                             multiplier: 0.95, constant: 0.0)

      view.addConstraints([horConstraint, verConstraint, widConstraint, heiConstraint])
  }
ios swift ios-autolayout

Swift 3, iOS and Xcode 8: Part 3: Autolayout and relative contraints

Previously, we constrained a button based on app margins. We can do the same with other elements.

Add another button to the screen. Control drag from that to the other button we have. Then select Vertical spacing. A new constraint will be added to the Left pane under the views.

Click on that, and on left hand pane, click on the sizing tab. You can now change the value of the spacing. Change Constant to 16.

Now when you run the simulator, you can see the button is 16 pixels above the other button.

If you control drag from a ui element to a container, like the root container, then you’ll have the option to centre vertically or horizonally align, too.

ios ios-storyboard ios-autolayout

Swift, Xcode 8 and iOS: Part 2: Auto layout and margin constraints

Before we do any coding, we’ll work out how to use auto layout. Auto layout is the ability to expand/pin elements to the width, height etc of the varying screen sizes of iOS devices.

Go to your story board. On the right hand pane, open the file inspector tab. In the interface builder document section, ensure Use auto layout is clicked.

Now add a button to your layout. Place it near the bottom of the screen, in the left hand corner.

Normally, when you show this on a bigger device, the button won’t be at the bottom of the screen, but only at pixel 410 or whatever is standard on the screen size for which you’re designing.

Let’s add an auto-layout constraints to change this. In the toolbar below the main design screen, there’s a little button that looks like a square X-Wing. It’s called pin. Click it. It should popup a dialogue.

First, uncheck the constrain to margins button. I don’t know what it means. I’ve been told to uncheck it. You should see a little graphic with four boxes around it, left, right, top, bottom.

Insert 16 in the left and right box and 20 in the bottom box. And click the little red lines. The button at the bottom should now say Add 3 contraints. Click that.

Open the app in different screen sizes via the simulator. The button should now expand at the bottom of the screen.

It will place it there irrespective of the actual width of the button that you set, or the vertical location: the auto layout constraints override that.

You can also click on the button on next to pin, which gives you update frames and update constraints options, which updates the views based on the auto layout values.

ios ios-storyboard ios-autolayout

Page 1 of 1