layout | title | description | date | category | tags | permalink | uuid |
---|---|---|---|---|---|---|---|
post |
Align: Intuitive Auto Layout |
I'm thrilled to introduce a new intuitive and powerful Auto Layout library - Align |
2017-11-17 18:00:00 +0300 |
programming |
ios |
/post/align |
00e90200-1ef8-479e-aea7-62b98a148c2e |
Align is an intuitive and powerful Auto Layout library. Designed to be simple and safe, Align is perfect for both new and seasoned developers.
If you'd like to learn about why it exists, who is it for, and why it might be the best tool for you, please continue. The best place to start using it is in a Playground available in the project. It's going to feel instantly familiar!
{% include ad-hor.html %}
The primary motivation for releasing Align was Chris Eidhof's article in which he shares his concerns about the current state of Auto Layout tools in Swift. When I was deciding how to work with Auto Layout in my recent Swift project I came to the same conclusions as Chris did. Among the tools that I've investigated (and took the best ideas from) were:
- PureLayout which I used in my Objective-C projects before. It was a great library in the Objective-C world, but even then it wasn't the one with the most concise syntax. In Swift it became even more apparent.
- Cartography, SnapKit. Both are pretty large and complex libraries. Operator overloads come with a good chance of increasing the app's compile time.
- Apple's NSLayoutAnchor API was created in the Objective-C era. I really like the idea behind anchors, but the actual API is verbose, requires manually activating each constraint, and there is no API for creating multiple constraints at once.
So rather then pulling in a library I decided to write my own. The goal was to hit a balance between power and simplicity. I felt like I had a pretty good chance of achieving that. After all, I already had plenty of experience working with Auto Layout. The first time we adopted it in our projects was back in iOS 6 days. More recently I made Arranged (UIStackView backport) and wrote about UIStackView under the hood. I had a good idea of I wanted from this tool.
Align has quite a few advantages over other frameworks.
- Align strives for clarity and simplicity by following Swift API Design Guidelines. Although most of the APIs are compact, it is a non-goal to enable the most concise syntax possible.
- Align has a fluent API that makes use sites form grammatical English phrases. That's what makes Swift code really stand out for me.
- It's super small with less than 250 line of code (compare with 1000 lines and over 27 files in Cartography).
- There are no custom operators and thus no unexpected surprises like an increasing in your app's compile time.
- Align is designed to be approachable by new developers which benefit seasoned ones as well.
Align is a beautiful port city on the Black Sea and a great name for yet another layout tool with anchors.
Start by selecting an anchor or a collection of anchors of a view (or of a layout guide). Then use anchor's methods to create constraints.
Anchors represent layout attributes of a view including edges, dimensions, axis, and baselines.
The best way to access anchors is by using a special addSubview(_:constraints:)
method (supports up to 4 views). Here are some examples of what you can do using anchors:
view.addSubview(subview) {
$0.edges.pinToSuperview(insets: Insets(10)) // Pin to superview edges
}
view.addSubview(subview) {
$0.edges.pinToSuperviewMargins() // Or margins
}
view.addSubview(subview) {
$0.edges(.left, .right).pinToSuperview() // Fill along horizontal axis
$0.centerY.alignWithSuperview() // Center along vertical axis
}
With
addSubview(_:constraints:)
method you define a view hierarchy and layout views at the same time. It encourages splitting layout code into logical blocks and prevents some programmer errors (e.g. trying to add constraints to views which are not in a view hierarchy).
Each anchor and collection of anchors have methods tailored for that particular kind of anchor:
view.addSubview(title, subtitle) { title, subtitle in
// Align one anchor with another
subtitle.top.align(with: title.bottom + 10)
// Align center with a superview
title.centerX.alignWithSuperview()
// Manipulate dimensions
title.width.set(100)
subtitle.width.match(title.width * 2)
// Change a priority of constraints inside a group:
subtitle.bottom.pinToSuperview().priority = UILayoutPriority(999)
}
All anchors are also accessible via .al
proxy:
title.al.top.pinToSuperview()
Align has full test coverage. If you'd like to learn about which constraints (
NSLayoutConstraint
) Align creates each time you call one of its methods, test cases are a great place to start.