π JSConstraints
π‘ A tiny Swift library written with only one thing in mind: Blazin' Fast Programmatic Constraints-Typing.
JSConstraints is a really small library extending UIView
and UIStackView
functionalities.
Table Of Content
π₯ Installation
JSConstraints is available through CocoaPods and Swift Package Manager.
Cocoapods
To install via Cocoapods, simply add the following line to your Podfile:
pod 'JSConstraints'
Swift Package Manager
Using SPM instead? In Xcode project, select File > Swift Package > Add Package Dependecy and paste the URL below.
https://github.com/jaysack/JSConstraints
π How It Works?
JSConstraints removes all unecessary boilerplate code needed when creating programmatic constraints.
Simply use one of the methods below to constraint any view:
setConstraints()
centerIn()
pintTo()
// Default
foo.setConstraints([ .top(view.topAnchor) ])
// Shortcut
foo.π([ .top(view.topAnchor) ])
Import Library
First, import the library
import JSConstraints
Square
The .square()
enum is pretty straight forward and allows you to make "squared" view. It sets both, width and height, to the value provided.
pinkSquare.setConstraints([ .square(185) ])
What Just Happened?
We set both width
and height
constraints to 185
.
Directional Constraints
// 1. Add to superview
view.addSubview(pinkSquare)
// 2. Set constraints
pinkSquare.setConstraints([
.leading(view.leadingAnchor),
.bottom(view.bottomAnchor) + .constant(18)
])
What Just Happened?
- We constrained
pinkSquare
to its superview's leading anchor.
let leadingConstraint = .leading(view.leadingAnchor)
- We then constrained
pinkSquare
again 18 points aways from its superview bottom anchor.
let bottomConstraint = .bottom(view.bottomAnchor) + .constant(18)
Refactored Form
Letβs put it all back together, and we get:
// Add pink square to superview
view.addSubview(pinkSquare)
// Set constraints
pinkSquare.π([ bottomConstraint, leadingConstraint ])
π‘ constant
argument is optional and replaced by 0 if not provided.
Reliative Constraints
indigoView.setConstraints([
.relWidth(view.widthAnchor) * .multiplier(0.4),
.relHeight(pinkSquare.heightAnchor) * .multiplier(1.18)
])
// We're assuming here that the indigo view's in already in
// its superview's stack and has been constrained from its top and right sides.
What Just Happened?
We set the width of indigoView
to be 0.4 times the size of view
width.
We also set indigoView
to be slightly taller than our pinkSquare
.
π‘ multiplier
argument is optional and replaced by 1 if not provided.
Centering a View
yellowCircle.centerIn(superview: self.view)
What Just Happened?
We constrained yellowCircle
in the center of the the screen.
Pin to Superview
indigoView.pinTo(superview: self.view, withPadding: 18)
β οΈ What About UILayoutGuide
Cases?
Depending on your design, you may opt to pin your view to either your ViewController's view
or it's layoutGuide
as both are supported with JSConstraints.
Using layoutGuide
will automatically add a child view to the layout guide's owner view:
indigoView.pinTo(layoutGuide: view.safeAreaLayoutGuide)
// Indigo view was automatically added to `view` subviews
β»οΈ How About Dynamic Constraints?
JSConstraints methods always return the collection of successfully activated constraints.
We can use it to toggle between active
and inactive
states.
1. Get Active Constraints
// Save returned constraints
var pinkOptionalConstraints = pinkSquare.setConstraints([ bottomConstraint, leadingConstraint ])
var indigoOptionalConstraints = indigoView.setConstraints([ topConstraint, trailingConstraint ])
// Append to array of dynamic constraints
dynamicConstraints.append(contentsOf: pinkOptionalConstraints)
dynamicConstraints.append(contentsOf: indigoOptionalConstraints)
Here, a list of activated constraints of type [NSLayoutConstraint]
is returned to us. We can save the result in dynamicConstraints
variable.
2. Update Constraints
// Deactivate optional constraints
dynamicConstraints.forEach { $0.isActive = false }
// Set new constraints
[pinkSquare, indigoView].forEach { $0.centerIn(superview: view) }
Here, weβre deactivating our optional constraints, then, adding new constraints.
3. Animation
βοΈ Author
Jonathan Sack
[email protected]
π License
Copyright Β© 2020 Jonathan Sack
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.