To run the example project, clone the repo, and run Example project only used for testing so farpod install from the Example directory first.
constrain is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'constrain'This library lets you quickly and efficiently set up a number of constraints using intuitive chaining syntax. For example:
let containerView = UIView()
let newView = UIView()
let centeredView = UIView()
containerView.constainSubview(newView).fillSafely()
centeredView.constrainIn(containerView).center()You can start the chain by typing any of these, depending on what you’re trying to do:
Called on view to be constrained:
- constrain
- constrainIn()
Called on superview or VC of superview:
- constrainSubview()
- constrainChild() - also handles view controller parent/child relationships, argument must be a VC. Optional argument for if you want the view to be a subview of a different view than the VC's view.
- constrainSibling()
- constrainSiblingToBottom()
- constrainSiblingToTrailing()Then you chain the constraints you want to make. They parameters default to zero padding and to relevant anchors on the superview, so for example you can just use view.constrain.top() if you want to constrain it to the superview’s top with no margin.
There’s also compound ones that handle common sets of constraints, like fillWidth() is leading + trailing, fillHeight() is top + bottom, and fill() is all 4.
There are "safe" versions of top and bottom that use the safe areas, and corresponsing fillSafely and fillHeightSafely. There's also centerSafely.
Notes:
- All constraints are enabled by default
- Adding subviews is handled by
constrainSubview(),constrainIn(),constrainSibling(),constrainSiblingToTrailing(), orconstrainSiblingToBottom(). If you need to add more constraints at a later time, just callconstrainsubsequently to avoid redoing it, although there's no harm in it. translatesAutoresizingMaskIntoConstraintsis always set to false- Most methods can also be called with View Controllers, but only the
constrainChild()method handles parent/child UIViewController relationships. Callremove()to undo it. - Trailing and Bottom constraints invert the input constant so it functions more as padding. Be careful with this if you want to change the constant in the future, as the inversion will not be preserved!
func viewDidLoad() {
let subview = UIView()
constrainSubview(subview)
.top()
.fillWidth()
// -vs-
subview.constrainIn(view)
.top()
.fillWidth()
}It's a style thing. If you're calling it from inside a UIView or UIViewController, you can call constrainSubview directly, so it's a bit more concise. But there's something to be said for having the more relevant parts at the beginning of the line, since it's easier to scan quickly. For anything that's not being directly constrained to main view, you don't get the benefit of omitting anything, so constrainIn() makes more sense, so I often use it even at top level for consistency. Maybe we'll make similarly inverted versions of constrainTrailingSibling, constrainBelowSibling, and constrainToSibling; but the originals don't see a ton of use yet.
anconaesselmann, axel@anconaesselmann.com
constrain is available under the MIT license. See the LICENSE file for more info.