Constraid
Constraid is your personal NSLayoutConsraint
Aid. It’s job is to make it as simple as
possible for you to programmatically use AutoLayout in your iOS & MacOS projects.
For example if you have a child view (childView
) added as a subview of a parent
view (parentView
) and you want that child view to match the width of the parent view you would
normally do the following with AutoLayout:
childView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
NSLayoutConstraint(
item: childView,
attribute: .leadingEdge,
relatedBy: .equal,
toItem: parentView,
attribute: .leadingEdge,
multiplier: 1.0,
constant: 0.0
),
NSLayoutConstraint(
item: childView,
attribute: .trailingEdge,
relatedBy: .equal,
toItem: parentView,
attribute: .trailingEdge,
multiplier: 1.0,
constant: 0.0
)
])
However, with the aid of Constraid it is as simple as
flush(childView, withVerticalEdgesOf: parentView).activate()
or if you want to combine constraint collections you can do so as follows:
let constraints = flush(childView, withVerticalEdgesOf: parentView) +
center(childView, verticallyWithin: parentView)
constraints.activate()
The above is extremely useful when doing AutoLayout Animation or when you simply want to deactivate or activate a collection of constraints.
Setup
Carthage is the best way to add Constraid to your project.
Add the following to your Cartfile.
github "uptech/Constraid"
Follow the Carthage instructions for adding frameworks to your application.
Usage
Constraid tries to simplify things by building on top of the lower level constructs provided by Apple’s AutoLayout system.
In general Constraid provides a number of methods that aid with defining constraint relationships between views. Currently, the provided methods are grouped into the following sections.
Flush
Lets say you want viewA
to sit flush or right along viewB
‘s edges, meaning be
sized the same size as viewB
. You can accomplish this by using the following:
flush(viewA, withEdgesOf: viewB)
If on the other hand you wanted viewA
to fill the space of viewB
up to viewB
’s
margins, you could simply do.
flush(viewA, withMarginsOf: viewB)
The flush
methods simply create one or more equivalency constraints between the two views
and the appropriate attributes. A list of the short versions of all the flush
methods are provided below.
flush(viewA, withLeadingEdgeOf: viewB)
flush(viewA, withTrailingEdgeOf: viewB)
flush(viewA, withTopEdgeOf: viewB)
flush(viewA, withBottomEdgeOf: viewB)
flush(viewA, withVerticalEdgesOf: viewB)
flush(viewA, withHorizontalEdgesOf: viewB)
flush(viewA, withEdgesOf: viewB)
flush(viewA, withLeadingMarginOf: viewB)
flush(viewA, withTrailingMarginOf: viewB)
flush(viewA, withTopMarginOf: viewB)
flush(viewA, withBottomMarginOf: viewB)
flush(viewA, withVerticalMarginsOf: viewB)
flush(viewA, withHorizontalMarginsOf: viewB)
flush(viewA, withMarginsOf: viewB)
Center
Ok so you want viewA
to be centered inside of viewB
’s edges. You can accomplish this by
using the following:
center(viewA, within: viewB)
If on the other hand you wanted viewA
to be centred inside of viewB
s margins you could
simply do.
center(viewA, withinMarginsOf: viewB)
The center
methods simply create one or more equivalency constraints between the two views
and the appropriate attributes (centerX
, centerY
, centerXwithinMargins
,
centerYwithinMargins
). A list of the short versions of all the center
methods are provided below.
center(viewA, verticallyWithin: viewB)
center(viewA, horizontallyWithin: viewB)
center(viewA, within: viewB)
center(viewA, verticallyWithinMarginsOf: viewB)
center(viewA, horizontallyWithinMarginsOf: viewB)
center(viewA, withinMarginsOf: viewB)
Cup
Lets say you want viewA
to sit flush or right along viewB
’s leading, top,
and trailing edges. You can accomplish this by using the following:
cup(viewA, byTopEdgeOf: viewB)
If on the other hand you wanted viewA
to sit flush or right along viewB
up to viewB
’s
leading, top, and trailing margins, you could simply do.
cup(viewA, byTopMarginOf: viewB)
The cup
methods simply create three equivalency constraints between the two
views and the appropriate attributes to cup the viewA
along 3 edges. A list
of the short versions of all the cup
methods are provided below.
cup(viewA, byTopEdgeOf: viewB)
cup(viewA, byBottomEdgeOf: viewB)
cup(viewA, byLeadingEdgeOf: viewB)
cup(viewA, byTrailingEdgeOf: viewB)
cup(viewA, byTopMarginOf: viewB)
cup(viewA, byBottomMarginOf: viewB)
cup(viewA, byLeadingMarginOf: viewB)
cup(viewA, byTrailingMarginOf: viewB)
Manage Size
Lets say you want viewA
’s width to be explicitly sized to some 100 pts. You can accomplish
this by using the following:
setWidth(of: viewA, to: 100)
If on the other hand you wanted viewA
’s height to be explicitly sized to 100 pts you would
do.
setHeight(of: viewA, to: 100)
The setWidth
and setHeght
methods simply create one or more equivalency constraints
between the view and the appropriate attributes. A list of the short versions
of all the setWidth
and setHeight
methods are provided below.
setWidth(of: item, to: constant)
setHeight(of: item, to: constant)
If you want to expand from a minimum width you can do so using the following:
expandWidth(of: item, from: constant)
expandHeight(of: item, from: constant)
limitWidth(of: item, by: constant)
limitHeight(of: item, by: constant)
Similarly, if you want to make the width of one view equal to another view’s width you can do this:
matchWidth(of: viewA, to: viewB)
And for the height:
matchHeight(of: viewA, to: viewB)
When you want to make a view’s height and width equal you can do:
equalize(viewA)
Manage Relative Position
Lets say you want viewA
to be position right after viewB
’s edge. You can accomplish this
by using the following:
follow(theTrailingEdgeOf: viewB, with: viewA)
Or lets say you want viewA
to be positioned in front of viewB
’s edge. You could do the
following.
precede(theLeadingEdgeOf: viewB, with: viewA)
If on the other hand you want to control the vertical position you can use set
.
These methods simply create one or more equivalency constraints between the two views and the appropriate attributes. A list of the short versions of all these methods are provided below.
follow(theTrailingEdgeOf:with:)
follow(theTrailingMarginOf:with:)
precede(theLeadingEdgeOf:with:)
precede(theLeadingMarginOf:with:)
set(viewA, aboveTheTopEdgeOf:)
set(viewA, aboveTheTopMarginOf:)
set(viewA, belowTheBottomEdgeOf:)
set(viewA, belowTheBottomMarginOf:)
Limit
Lets say you want viewA
to be limited by viewB
’s edges. You can accomplish this by using
the following:
limit(viewA, byEdgesOf: viewB)
This sets up constraints saying that each of viewA
’s edges must be <=
viewB
’s
respective edges.
If on the other hand you wanted viewA
limited by viewB
s margins you could
simply do.
limit(viewA, byMarginsOf: viewB)
The limit
methods simply create one or more <=
constraints between the two views and the
appropriate attributes. A list of the short versions of all the limit
methods are provided
below.
limit(viewA, byLeadingEdgeOf: viewB)
limit(viewA, byTrailingEdgeOf: viewB)
limit(viewA, byTopEdgeOf: viewB)
limit(viewA, byBottomEdgeOf: viewB)
limit(viewA, byVerticalEdgesOf: viewB)
limit(viewA, byHorizontalEdgesOf: viewB)
limit(viewA, byEdgesOf: viewB)
limit(viewA, byLeadingMarginOf: viewB)
limit(viewA, byTrailingMarginOf: viewB)
limit(viewA, byTopMarginOf: viewB)
limit(viewA, byBottomMarginOf: viewB)
limit(viewA, byVerticalMarginsOf: viewB)
limit(viewA, byHorizontalMarginsOf: viewB)
limit(viewA, byMarginsOf: viewB)
Expand
Lets say you want viewA
to be expanded from viewB
’s edges out. You can accomplish this
by using the following:
expand(viewA, fromEdgesOf: viewB)
This sets up constraints saying that each of viewA
’s edges must be >=
viewB
’s
respective edges.
If on the other hand you wanted viewA
to be expanded from viewB
s margins you could
simply do.
expand(viewA, fromMarginsOf: viewB)
The expand
methods simply create one or more >=
constraints between the two views and
the appropriate attributes. A list of the short versions of all the expand
methods are
provided below.
expand(viewA, fromLeadingEdgeOf: viewB)
expand(viewA, fromTrailingEdgeOf: viewB)
expand(viewA, fromTopEdgeOf: viewB)
expand(viewA, fromBottomEdgeOf: viewB)
expand(viewA, fromVerticalEdgesOf: viewB)
expand(viewA, fromHorizontalEdgesOf: viewB)
expand(viewA, fromEdgesOf: viewB)
expand(viewA, fromLeadingMarginOf: viewB)
expand(viewA, fromTrailingMarginOf: viewB)
expand(viewA, fromTopMarginOf: viewB)
expand(viewA, fromBottomMarginOf: viewB)
expand(viewA, fromVerticalMarginsOf: viewB)
expand(viewA, fromHorizontalMarginsOf: viewB)
expand(viewA, fromMarginsOf: viewB)
expand(viewA, fromWidthOf: viewB)
expand(viewA, fromHeightOf: viewB)
Manage Intrinsic Size Relations
These allow you to define the content hugging and compression resistance priorities and constraints for a given view. Note: The priorities are linked so that they will be the same. If you want to set them independently you should use the native API provided by Apple for this.
keepIntrinsicHeight(of: viewA, priority:)
keepIntrinsicWidth(of: viewA, priority:)
keepIntrinsicSize(of: viewA, priority:)
Build
We supports Carthage and therefore this project can be built using the following.
carthage build --no-skip-current
However, if you don’t want to use Carthage or you are having difficulties with build failures you can try the following which should provide some more details.
xcodebuild -scheme Constraid-MacOS -project Constraid.xcodeproj build
xcodebuild -scheme Constraid-iOS -project Constraid.xcodeproj build
License
Constraid
is Copyright © 2017-2018 UpTech Works, LLC. It is free software, and
may be redistributed under the terms specified in the LICENSE file.
Our Mascots
The mascots for our project are the work of Ron Leishman. We licensed them and they are available for licensing if you like from shutterstock.
About 
Constraid
is maintained and funded by UpTech Works, LLC, a
software product, design & development consultancy.
We love open source software. See our other projects or hire us to design, develop, and grow your product.