ConstrainTo is a simple and tiny extension to UIView
, that aims to simplify the common use cases of AutoLayout without trying to introduce new paradigms.
ConstrainTo removes a lot of boiler plate code by automatically:
- Setting
translatesAutoresizingMaskIntoConstraints
tofalse
on the view being constrained - Automatically activating created constraints by setting
isActive
totrue
- Returning all constraints that have been created in case you need access to them in the future
ConstrainTo has 2 main methods:
@discardableResult func constrain(_ attribute: NSLayoutConstraint.Attribute, being relation: NSLayoutConstraint.Relation = .equal, to viewAttribute: NSLayoutConstraint.Attribute, of view: UIView, multipliedBy multiplier: CGFloat = 1.0, offsetBy offset: CGFloat = 0.0, activate: Bool = true, priority: UILayoutPriority = .required) -> NSLayoutConstraint
@discardableResult func constrain(_ attribute: NSLayoutConstraint.Attribute, being relation: NSLayoutConstraint.Relation = .equal, to constant: CGFloat, activate: Bool = true, priority: UILayoutPriority = .required) -> NSLayoutConstraint
In addition to 7 convenience methods:
@discardableResult public func constrain(to attribute: NSLayoutConstraint.Attribute, of view: UIView, multipliedBy multiplier: CGFloat = 1.0, offsetBy offset: CGFloat = 0.0) -> NSLayoutConstraint
@discardableResult public func constrain(to size: CGSize) -> (width: NSLayoutConstraint, heightConstraint: NSLayoutConstraint)
@discardableResult public func constrain(to view: UIView, insetBy insets: UIEdgeInsets = .zero) -> (topConstraint: NSLayoutConstraint, leftConstraint: NSLayoutConstraint, bottomConstraint: NSLayoutConstraint, rightConstraint: NSLayoutConstraint)
@discardableResult public func constrain(toEdgesOf view: UIView, insetBy insets: UIEdgeInsets = .zero) -> (topConstraint: NSLayoutConstraint, leadingConstraint: NSLayoutConstraint, bottomConstraint: NSLayoutConstraint, trailingConstraint: NSLayoutConstraint)
@discardableResult public func constrain(toMarginsOf view: UIView, insetBy insets: UIEdgeInsets = .zero) -> (topMarginConstraint: NSLayoutConstraint, leadingMarginConstraint: NSLayoutConstraint, bottomMarginConstraint: NSLayoutConstraint, trailingMarginConstraint: NSLayoutConstraint)
@discardableResult public func constrain(toCenterOf view: UIView, offsetBy offsets: CGPoint = .zero) -> (xConstraint: NSLayoutConstraint, yConstraint: NSLayoutConstraint)
@discardableResult public func constrain(toSizeOf view: UIView) -> (widthConstraint: NSLayoutConstraint, heightConstraint: NSLayoutConstraint)
If you wanted the left of redView
to be to the right of blueView
you would need to write:
redView.constrain(.left, being: .equal, to: .right, of: blueView, multipliedBy: 1, offsetBy: 0, activate: true, priority: .required)
But because of default parameters you just need to write:
redView.constrain(.left, to: .right, of: blueView)
If you wanted the left of redView
to be 10 pts to the right of blueView
you would need to write:
redView.constrain(.left, to: .right, of: blueView, offsetBy: 10)
If you want to constrain the width of redView
to 20 pts you would need to write:
redView.constrain(.width, being: .equal, to: 20, activate: true, priority: .required)
But because of default parameters you just need to write:
redView.constrain(.width, to: 20)
If you want to constrain the width of redView
to the width of blueView
you would write:
redView.constrain(to: .width, of: blueView, multipliedBy: 1, offsetBy: 0)
But because of default parameters you just need to write:
redView.constrain(to: .width, of: blueView)
If you want to constrain the size of redView
to 20 x 20 pts you would need to write:
redView.constrain(to: CGSize(width: 20, height: 20))
If you want to constrain the frame (top, left, bottom and right) of redView
to that of blueView
you would need to write:
redView.constrain(to: blueView, insetBy: UIEdgeInsets.zero)
But because of default parameters you just need to write:
redView.constrain(to: blueView)
If you want to constrain the frame of redView
to be inset 10 pts to all edges of blueView
you would need to write:
redView.constrain(to: blueView, insetBy: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
If you want to constrain the edges (top, leading, bottom and trailing) of redView
to that of blueView
you would need to write:
redView.constrain(toEdgesOf: blueView, insetBy: .zero)
But because of default parameters you just need to write:
redView.constrain(toEdgesOf: blueView)
If you want to constrain the edges of redView
to be inset 10 pts to all edges of blueView
you would need to write:
redView.constrain(toEdgesOf: blueView, insetBy: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
If you want to constrain the margins (top margin, leading margin, bottom margin and trailing margin) of redView
to that of blueView
you would need to write:
redView.constrain(toMarginsOf: blueView, insetBy: .zero)
But because of default parameters you just need to write:
redView.constrain(toMarginsOf: blueView)
If you want to constrain the margin's of redView
to be inset 10 pts to all edges of blueView
you would need to write:
redView.constrain(toMarginsOf: blueView, insetBy: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
If you want to constrain redView
to be centered in blueView
you would need to write:
redView.constrain(toCenterOf: blueView, offsetBy: .zero)
But because of default parameters you just need to write:
redView.constrain(toCenterOf: blueView)
If you want to constrain the center of redView
to be 10 pts to below the center blueView
you would need to write:
redView.constrain(toCenterOf: blueView, offsetBy: CGPoint(x: 0, y: 10))
If you want to constrain the size of redView
to the size of blueView
you would need to write:
redView.constrain(toSizeOf: blueView)