JSConstraints 1.2.0

JSConstraints 1.2.0

Maintained by Jonathan Sack.



  • By
  • Jonathan Sack

πŸ”— JSConstraints

Version CI Platform License

πŸ’‘ 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

Pink square in Xcode simulator

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

Pink constraints to left and bottom in Xcode simulator

// 1. Add to superview
view.addSubview(pinkSquare)

// 2. Set constraints
pinkSquare.setConstraints([
    .leading(view.leadingAnchor),
    .bottom(view.bottomAnchor) + .constant(18)
])

What Just Happened?

  1. We constrained pinkSquare to its superview's leading anchor.
let leadingConstraint = .leading(view.leadingAnchor)

  1. 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

Pink constraints to left and bottom in Xcode simulator

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

Yellow circle in Xcode simulator

yellowCircle.centerIn(superview: self.view)

What Just Happened?

We constrained yellowCircle in the center of the the screen.



Pin to Superview

Indigo view pinned to superview in Xcode simulator

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

 Subviews animations



βœ‰οΈ 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.