Layout Expressions
LayoutExpressions is a lightweight and easy-to-use library for defining Auto Layout constraints, designed for Swift. It lets you describe constraints expressively and with type safety:
NSLayoutConstraint.activateLayout {
subviewB.anchors.allEdges == subviewA.anchors.allEdges - 10
}
instead of:
let top = subview.topAnchor.constraint(equalTo: container.topAnchor, constant: 10)
let bottom = subview.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -10)
let leading = subview.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 10)
let trailing = subview.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -10)
NSLayoutConstraint.activate([top, bottom, leading, trailing])
This example uses a Composite Expression to create four constraints from a single expression. More details below.
Usage
Add NSLayoutConstraints
to your views by typing your constraints as view1.attribute1 == view2.attribute2 × multiplier + constant
.
You can use any of ==
, >=
, or <=
as relations, and you can omit the multiplier and constant if they aren't needed:
// A basic layout expression for the y-axis:
subview.anchors.top == container.anchors.top
// With multiplier and constant:
subview2.anchors.width >= subview1.anchors.width * 2 + 10
LayoutExpressions supports Swift 5.1 function builders, allowing you to easily create dynamic layouts:
NSLayoutConstraint.activateLayout {
if pinTopAndBottomToSafeArea {
subview.anchors.verticalEdges == container.anchors.safeArea.verticalEdges
} else {
subview.anchors.verticalEdges == container.anchors.verticalEdges
}
subview.anchors.horizontalEdges == container.anchors.horizontalEdges
}
To access the constraints without activating them you can use evaluateLayout()
instead of activateLayout()
:
let constraints = NSLayoutConstraint.evaluateLayout {
subview.anchors.center == container.anchors.center
}
// `constraints` contains a .centerX constraint and a .centerY constraint
Set priorities for your constraints by using the <~
operator after your expression:
subview1.anchors.width >= subview2.anchors.width <~ .defaultHigh
LayoutExpressions provides the following extensions for layout anchors:
View Anchors | Layout Guide Anchors |
-----------------------------|----------------------------|
view.anchors.top
| guide.anchors.top
|
view.anchors.bottom
| guide.anchors.bottom
|
view.anchors.leading
| guide.anchors.leading
|
view.anchors.trailing
| guide.anchors.trailing
|
view.anchors.left
| guide.anchors.left
|
view.anchors.right
| guide.anchors.right
|
view.anchors.centerX
| guide.anchors.centerX
|
view.anchors.centerY
| guide.anchors.centerY
|
view.anchors.width
| guide.anchors.width
|
view.anchors.height
| guide.anchors.height
|
view.anchors.firstBaseline
| |
view.anchors.lastBaseline
| |
As well as convenience shorthands for accessing the anchors of common layout guides:
UIView | |
------------------------|---------------------------|
Safe Area | view.anchors.safeArea.*
|
Layout Margins | view.anchors.margins.*
|
Readable Content Guide | view.anchors.readable.*
|
These shorthands can further simplify layout expressions that use layout guides, for example: subview.anchors.top == container.anchors.safeArea.top
Composite Expressions
LayoutExpressions makes common layout patterns even easier with composite expressions. Composite expressions are expressions that evaluate to more than one NSLayoutConstraint
.
For example, subview.anchors.allEdges == container.anchors.allEdges
will pin all edges of subview
to container
. This expression evaluates to four distinct NSLayoutConstraints
-- one for each edge. Use them to make your code even more concise and clear.
LayoutExpressions provides the following extensions for composite layout anchors:
View Anchors | LayoutGuide Anchors |
--------------------------------|----------------------------------|
view.anchors.allEdges
| guide.anchors.allEdges
|
view.anchors.verticalEdges
| guide.anchors.verticalEdges
|
view.anchors.horizontalEdges
| guide.anchors.horizontalEdges
|
view.anchors.center
| guide.anchors.center
|
view.anchors.size
| guide.anchors.size
|
Edges
view.anchors.allEdges
evaluates to constraints for .top
, .bottom
, .leading
, and .trailing
. All relations are supported: ==
, >=
, <=
.
// Pin the edges of subview to container.
subview.anchors.allEdges == container.anchors.allEdges
// Use the '-' operator to inset all edges of subview by 10 pts.
subview.anchors.allEdges == container.anchors.allEdges - 10
view.anchors.verticalEdges
evaluates to constraints for .top
and .bottom
; and view.anchors.horizontalEdges
evaluates to constraints for .leading
and .trailing
. All relations are supported: ==
, >=
, <=
.
// Pin the vertical edges of subview to the container's safe area.
subview.anchors.verticalEdges == container.anchors.allEdges
// Pin the horizontal edges of subview to the container, inset by 10 pts.
subview.anchors.horizontalEdges == container.anchors.horizontalEdges - 10
Size
view.anchors.size
evaluates to constraints for .width
and .height
. All relations are supported: ==
, >=
, <=
.
// Pin the size of subview to the size of container.
subview.anchors.size == container.anchors.size
// Pin the size of subview to the size of container, with an offset.
subview.anchors.size == container.anchors.size + Size(width: -20, height: -10)
// Pin the size of subview to a fixed size.
subview.anchors.size == Size(width: 320, height: 200)
Center
anchors.center
evaluates to constraints for .centerX
and .centerY
. Only the ==
relation is supported.
// Pin the center of subview to the center of container.
subview.anchors.center == container.anchors.center
// Pin the center of subview to the center of container, with an offset.
subview.anchors.center == container.anchors.center + Offset(horizontal: 0, vertical: -10)
Installation
LayoutExpressions supports macOS 10.13+, iOS 9.0+, and tvOS 9.0+.
Swift Package
In Xcode 11, use the repository URL in the Swift Packages screen:
https://github.com/stevebrambilla/LayoutExpressions
Carthage
If you’re using Carthage, simply add LayoutExpressions to your Cartfile
:
github "stevebrambilla/LayoutExpressions" ~> 2.0
Contact
License
LayoutExpressions is available under the MIT license. See the LICENSE file for more info.
Github
link |
Stars: 11 |
Help us keep the lights on
Dependencies
Used By
Total: 0
Releases
2.0.0-beta.1 - Jul 25, 2019
Change Log
- Added Swift Package compatibility
- Added support for macOS and macCatalyst
- Added support for Swift 5.1 function builders:
NSLayoutConstraint.activateLayout {
if pinTopAndBottomToSafeArea {
subview.anchors.verticalEdges == container.anchors.safeArea.verticalEdges
} else {
subview.anchors.verticalEdges == container.anchors.verticalEdges
}
subview.anchors.horizontalEdges == container.anchors.horizontalEdges
}
- Removed customizable per-edge insets from Edges expressions
- Renamed
.edges
anchor to.allEdges
- Added
.verticalEdges
and.horizontalEdges
anchors