constraints-kit
Declarative, Chainable & Lightweight Auto Layout constraints framework for iOS. The framework offers a rich set of methods for defining Auto Layout
constraints (see Contents
) without any other external dependencies.
? Movitation
The purpose of this framework is to provide a very lightweight solution for Auto Layout
and to make the development of programmatic UI
much simpler, hiding the boilerplate code under the framework. Primary usage is for internal developments, however I decided to share the framework with the community, since it offers some uniqueness and I'm going to continue work on this development.
? Demo
In order to create something like in the following screenshot:
You need to write just a few lines of code:
// 1. First you need to add all your views somewhere. That means your views must have a superview. Let's assume that you have done that.
// 2. Then we assume that visually your views are fully configured.
// 3. And finally, all we need to do is to specify the constraints:
cardView.pinInside(view: self.view, offset: 16)
imageView.pinInside(view: cardView, offset: 8)
blurView.pinInside(view: cardView)
titleLabel.pinTopToTopCenter(of: imageView, offset: 24)
button
.bottom(with: imageView, anchor: .bottom, offset: -34)
.center(in: imageView, axis: .horizontal)
.set(height: 60)
.set(aspect: 2/1)
label
.center(in: imageView)
.left(with: imageView, anchor: .left, offset: 16)
.right(with: imageView, anchor: .right, offset: -16)
Installation
CocoaPods
constraints-kit
is availabe via CocoaPods
pod 'constraints-kit', '~> 1.0.0'
Manual
You can always manually add the framework sources into your project. In order to do that just simply copy-paste the following files.
✈️ Usage
The framework is pretty easy to use, however I do recommend to learn the basics of Auto Layout
before installing the framework - it will help you to understand what the minimum number of constraints a UIView
needs to have and to avoid common pitfalls.
Import
After adding the framework to a project, simply add an import statemt:
import constraints_kit
Setting size
view.set(size: CGSize(width: 300, height: 300))
view.set(width: 400)
view.set(height: 200)
view
.set(width: 200)
.set(aspect: 2/1)
Constraining
A UIImageView
fills the parent UIView
with offset, until the bottom anchor reaches the top
anchor of the UIButton
:
imageView
.constrain(using: .top, to: .top, of: view, offset: 24)
.constrain(using: .right, to: .right, of: view, offset: -24)
.constrain(using: .left, to: .left, of: view, offset: 24)
.constrain(using: .bottom, to: .top, of: button, offset: -24)
A UIImageView
is anchored at the center of the parent view, it's stretched to the horizontal
axis by anchoring left
& right
sides with the aspect ratio
of 3 to 2
:
imageView
.center(in: view, axis: .vertical)
.left(with: view, anchor: .left)
.right(with: view, anchor: .right)
.set(aspect: 3/2)
Anchoring
A custom UIView
fills a UICollectionViewCell
to the top
system spacing, with custom left
& right
offsets and to the top
anchor of the UIButton
:
presenterView
.topToSystemSpacing(with: view, anchor: .top)
.right( with: view, anchor: .right, offset: -16)
.left( with: view, anchor: .left, offset: 16)
.bottom( with: button, anchor: .top, offset: -16)
A UIButton
is placed at the center
of the parent view, its bottom
anchor is attached to the bottom of the parent view, height
is set to 60
with aspect ratio
of 2 to 1
:
button
.bottom(with: imageView, anchor: .bottom, offset: -34)
.center(in: imageView, axis: .horizontal)
.set(height: 60)
.set(aspect: 2/1)
Pinning
A custom ActivityIndicator
view is anchored to the top left corner of the specified view with some offset
and size
equals to 20 to 20
:
activityIndicator
.pinInsideToTopLeftCorner(of: view, offset: 24)
.size(CGSize(width: 20, height: 20))
Advanced case where top left anchor of a custom ProgressView
is attached to the top leading corner of the parent view and the bottom right anchor is attached to the top right anchor of the LogIn
button:
progressView
.pin(anchors: [.left, .top], toTargetView: view, using: [.leading, .top])
.pin(anchors: [.bottom, .right], toTargetView: button, using: [.right, .top])
Filling
A UITableView
is placed inside the parent UIView
and fills the top half of it (using left
, top
, right
and centerX
anchors):
tableView.fillTopHalf(of: parentView)
A UICollectionView
is placed inside the parent UIView
and fills the left half of it with the specified offset (using left
, top
, bottom
and centerY
anchors):
collectionView.fillLeftHalf(of: splitView, offset: 16)
? Contents
The kit contains several groups of methods, each with a specific purpose. All the groups can be chained together, however you should keep in mind that if you have conflicting constraints or you don't provide enough information for the Auto Layout
engine, you will see no effect or some unexpected results. It's assumed that you already know the basics of Auto Layout
.
Common
constrain
- constrainsself
using the specifiedAttribute
to the specifiedAttribute
with respect to the relatedUIView
. You may setRelation
(which is by default.equal
),offset
(default is0.0
) andmultiplier
(default is1.0
)fit
- placesself
inside the specifiedUIView
with an optionaloffset
(default is0.0
)center
- centersself
inside the specifiedUIView
using a concreteAxis
case, with an optionalmultiplier
(default is1.0
)width
- applies width equalization betweenself
and the specifiedUIView
. You may change theRelation
(default isequal
),UILayoutPriority
(default isrequired
),multiplier
(default is1.0
) andconstant
(default is0.0
)height
- applies height equalization betweenself
and the specifiedUIView
. You may change theRelation
(default isequal
),UILayoutPriority
(default isrequired
),multiplier
(default is1.0
) andconstant
(default is0.0
)
Setters
set(size:)
- sets a newCGSize
forself
by applying layout constaints forwidth
&height
anchorsset(width:)
- sets a newwidth
by applying layout constaint forwidth
anchorset(height:)
- sets a newheight
by applying layout constraint forheight
anchorset(aspect:)
- sets a newaspect ratio
by applying layout constaint foraspect
anchorset(aspectOf:)
- sets a newaspect ratio
by duplicatingaspect
of the specifiedUIView
set(value: to:)
- sets a new offsetvalue
for theAttribute
Anchoring
top
- anchors top anchor to the specifiedUIView
usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)bottom
- anchors bottom anchor to the specifiedUIView
usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)left
- anchors left anchor to the specifiedUIView
usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)right
- anchors right anchor to the specifiedUIView
usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)
Anchoring to System Spacing
rightToSystemSpacing
- anchors right anchor to the specifiedUIView
with respect to System Spacing usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)leftToSystemSpacing
- anchors left anchor to the specifiedUIView
with respect to System Spacing usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)topToSystemSpacing
- anchors top anchor to the specifiedUIView
with respect to System Spacing usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)bottomToSystemSpacing
- anchors bottom anchor to the specifiedUIView
with respect to System Spacing usingAxisY
anchor,Relation
(defatul is.equal
), NSLayoutPriority (default is.required
) andoffset
(default is0.0
)
Pinning
pinTopLeftToTopLeftCorner
- pins Top Left anchor to the Top Left corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinTopRightToTopRightCorner
- pins Top Right anchor to the Top Right corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinBottomRightToBottomRight
- pins Bottom Right anchor to the Bottom Right corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinBottomLeftToBottomLeft
- pins Bottom Left anchor to the Bottom Left corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinBottomRightToTopLeft
- pins Bottom Right anchor to the Top Left corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinBottomLeftToTopRight
- pins Bottom Left anchor to the Top Right corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinTopLeftToBottomRight
- pins Top Left anchor to the Bottom Right corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinBottomRightToTopLeft
- pins Bottom Right anchor to the Top Left corner of the specifiedUIView
with a givenoffset
(default is0.0
)pinTopToTopCenter
- pins Top anchor to the Top Center anchor of the specifiedUIView
with a givenoffset
(default is0.0
)pinBottomToBottomCenter
- pins Bottom anchor to the Bottom Center anchor of the specifiedUIView
with a givenoffset
(default is0.0
)pinLeftToLeftCenter
- pins Left anchor to the Left Center anchor of the specifiedUIView
with a givenoffset
(default is0.0
)pinRightToRightCenter
- pins Right anchor to the Right Center anchor of the specifiedUIView
with a givenoffset
(default is0.0
)pinInside
- pinsself
inside the specifiedUIView
withRelation
(default is.equal
), UILayoutPriority (default is.required
) andoffset
(default is0.0
)pinTo
- pinsself
to the specifiedUIView
by usingAnchor
(which is anOptionSet
)pin(anchors:, toTargetView: , using:)
- pins the specifiedAnchors
ofself
to theUIView
by using the relatedAnchors
Filling
fillBottomHalf
- fills the bottom half of the specified view byself
with the givenoffset
(default is0.0
)fillTopHalf
- fills the top half of the specified view byself
with the givenoffset
(default is0.0
)fillLeftHalf
- fills the left half of the specified view byself
with the givenoffset
(default is0.0
)fillRightHalf
- fills the right half of the specified view byself
with the givenoffset
(default is0.0
)