Home

Positioning UIView Easily
Swift
iOS
UIKit

It's very common on UIKit where you create a parent - subview relationship between different views to compose complex view hierarchies. Today I'll show you how to do this easily using AutoLayout.

let parent = UIView()
let view = UIView()

parent.addSubview(view)

Positioning

Next step is to position the view with respect to the parent. For this, you'll need to create some constraints.

view.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraints.activate([
  view.topAnchor.constraint(equalTo: parent.topAnchor),
  view.bottomAnchor.constraint(equalTo: parent.bottomAnchor),
  view.leadingAnchor.constraint(equalTo: parent.leadingAnchor),
  view.trailingAnchor.constraint(equalTo: parent.trailingAnchor),
])

Padding

At this point, your view snapped right into its parent frame, but you may want to have some padding between them. You can simply modify the constraints to have these padding values while creating them.

NSLayoutConstraints.activate([
  view.topAnchor.constraint(equalTo: parent.topAnchor, constant: 10),
  view.bottomAnchor.constraint(equalTo: parent.bottomAnchor, constant: 10),
  view.leadingAnchor.constraint(equalTo: parent.leadingAnchor, constant: 10),
  view.trailingAnchor.constraint(equalTo: parent.trailingAnchor, constant: 10),
])

Extending UIView

Since this code will get very repetitive in your codebase, you can create an extension on UIView to simplify creating such constraints.

Pro tip, if you want to default insets to be zeroes, give insets a default parameter of UIEdgeInsets.zero.

extension UIView {

  func snap(to parent: UIView, insets: UIEdgeInsets = .zero ) {
        self.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate( [
            self.topAnchor.constraint(equalTo: parent.topAnchor, constant: insets.top),
            self.bottomAnchor.constraint(equalTo: parent.bottomAnchor , constant: -insets.bottom),
            self.leadingAnchor.constraint(equalTo: parent.leadingAnchor, constant: insets.left),
            self.trailingAnchor.constraint(equalTo: parent.trailingAnchor, constant: -insets.right),
        ])
    }

}