ZenLayout 0.3

ZenLayout 0.3

TestsTested
LangLanguage SwiftSwift
License MIT
ReleasedLast Release Sep 2015
SPMSupports SPM

Maintained by Andrey Ufimtsev.



  • By
  • Andrey Ufimtsev

ZenLayout

If you have ever had to write Auto Layout constraints in code, you probably know how painful it could be sometimes. ZenLayout is a small but smart library which aims to simplify the layout related programming and make it both convenient and enjoyable.

Disclaimer

ZenLayout is still under development, which means that until version 1.0.0 the compatibility with the previous versions of ZenLayout is not guaranteed. If you are using CocoaPods, consider specifying the desired version in the Podfile.

Usage

Simplified constraint syntax

The core feature of this library is the simplified constraint syntax. Let’s take a look at some of the native Cocoa Touch code used to place a label below a button and align their horizontal centers.

label.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addConstraint(NSLayoutConstraint(item: label,
                                 attribute: .Top,
                                 relatedBy: .Equal,
                                    toItem: button,
                                 attribute: .Bottom,
                                multiplier: 1,
                                  constant: 15))
view.addConstraint(NSLayoutConstraint(item: label,
                                 attribute: .CenterX,
                                 relatedBy: .Equal,
                                    toItem: button,
                                 attribute: .CenterX,
                                multiplier: 1,
                                  constant: 0))

And now let’s take a look at the same code done with ZenLayout:

view.addConstraint(label.top == button.bottom + 15)
view.addConstraint(label.centerX == button.centerX)

Impressive? Let’s continue then!

Writing a constraint

So, as you might have noticed, ZenLayout allows us to treat a constraint as an equation and write it in the following format:

view1.attribute == multiplier * view2.attribute + constant

Such an expression results in an object of NSLayoutConstraint class and you can store it inside a variable or put directly into the addConstraint() method:

let constraint = child.left == parent.left
parent.addConstraint(constraint)
// --- OR ---
parent.addConstraint(child.left == parent.left)

So, let’s practice a little bit more and make the label from one of the previous examples to be twice as high as the button:

view.addConstraint(label.height == 2 * button.height)

Notice that we don’t have to write setTranslatesAutoresizingMaskIntoConstraints(false) because it’s automatically called for the view on the left side of the equation (in this case for label).

Setting a constraint’s priority

Let’s say we have a constraint that makes the child’s height to be half of the parent’s height minus 4 and we want to set it’s priority to 100. Use the special !-syntax to do that:

child.height == 0.5 * parent.height - 4 ! 100

Convenience methods

In addition to the updated constraint syntax, ZenLayout also provides convenience methods to deal with more complex layout tasks. Each of these methods is named layout() and has a different set of parameters defining what that method does.

It’s important to keep in mind two things:

  1. All constraints generated by a layout() method are added to the view the method gets called on.
  2. The view coming as the first parameter to the layout() method gets its translatesAutoresizingMaskIntoConstraints property set to false.

Matching size. You can set the size of a view by calling layout(_:matchSize:):

layout(view, matchSize: CGSize(width: 50, height: 50))

Pinning to center. You can attach view’s center to the center of another view by calling layout(_:pinToCenterOf:) or you can call layout(_:pinToCenterOf:displacement:) to specify a displacement from the center:

layout(child, pinToCenterOf: parent, displacement: CGVector(dx: 15, dy: 20))

Pinning to edges. You can pin view’s edges to the edges of another view by calling layout(_:pinToEdgesOf:) or you can call layout(_:pinToEdgesOf:insets:) to specify insets:

layout(child,
    pinToEdgesOf: parent,
    insets: UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8))

Pinning to margins. You can pin view’s edges to the margins of another view by calling layout(_:pinToMarginsOf:) or you can call layout(_:pinToMarginsOf:insets:) to specify insets:

layout(child,
    pinToMarginsOf: parent,
    insets: UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8))

More coming! That’s right! This is far from the end.

Installation

ZenLayout is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "ZenLayout"

Why ZenLayout anyway?

Reason 1: It’s clean and simple. You no longer have to write a lot of code just to set view’s width and height in Auto Layout. And it’s actually very easy to see what is going on in your code when you open it after a long vacation.

Yeah, kinda… But there is a lot of libraries that allow you to do the same.

Reason 2: You don’t have to learn anything new to start using it. That’s it. These are the same constraints you used to write before. Just different style. You don’t need to remember any fancy methods. It’s very straightforward.

But I want those fancy methods! I want to set constraints for a bunch of views by writing only one line of code!

Reason 3: Convenience methods. It’s definitely good to have such a toolset under your hand. ZenLayout provides one, but will never force you to use it unless you feel comfortable with it.

Support

If you have a suggestion or you have found a bug, feel free to send me a mail to [email protected]. I would be also glad to know if you end up using ZenLayout in your project. Cheers!

License

ZenLayout is available under the MIT license. See the LICENSE file for more info.