Autolayout Constraints in Emoji — Maximum Readability

Programmatically creating Autolayout constraints is famously dense to read, although the strongly-typed visual format makes some easier to parse visually.

With that in mind, which is easier to read?

This:

let subView1 = UIView()
let subView2 = UIView
let constraint = NSLayoutConstraint(item: subView1, attribute: .left, relatedBy: NSLayoutRelation.equal, toItem: subView2, attribute: .right, multiplier: 1.0, constant: -10)
constraint.priority = 900.0
view.addConstraint(constraint)

Or this:1

view.📌(subView1 ⬇️=⬆️ subView2 + 10 ‼️ 900.0)

I wrote this as an exercise after reading a description of Erica Sadun’s talk and some posts of hers on the emoji as function name idea. I happened to read this around the time that I was needing to layout a number of views in code using autolayout and was overwhelmed with the verbosity.

So I started goofing. Basically, I use the “boxed arrow” emoji to indicate which edge is being constrained, and double arrows to indicate height/width. Then and “=” operator to indicate that two edges are constrained.

The “+” operator is overloaded to add a constant to the constraint, and the “‼️” emoji is overloaded to indicate priority. Sadly, I couldn’t find an emoji that was valid for use as an operator and that was as clear as the 📌 for communicating “add constraint, so I named a function “📌”.

Lastly, I probably could have just overloaded “+” again to add the constraints, but I ran out of time and it was simpler to overload ++ for adding different constraints.

Likewise, it would be useful to add “<=”, “>=” operators.

Anyway, I’m pretty happy with this fun project. I think that the example below demonstrates the use the syntax. I have also embedded my full playground as a gist.

and here is the layout code

// add one constraint at a time
view.📌(grayView |⬅️ 20.0)  //to superview margin
view.📌(grayView -⬆️ 20.0)
view.📌(grayView ⬇️- 20.0)
view.📌(grayView ➡️| 20.0)

// add multiple constraints (combined with ++ operator)
view.📌(redButton |⬅️ 60 ++ redButton -⬆️ 60 ++ redButton ↕️= 40 ++ redButton ↔️= 40)

// can add constants
view.📌(redButton ↔️=↔️ blueButton + 20)

// can add priorities
view.📌(redButton ⬇️=⬆️ blueButton + 100 ‼️ 800.0)
view.📌(redButton ⬇️=⬆️ blueButton + 10 ‼️ 900.0) 

view.📌(redButton |=| blueButton)  //align vertical centers
view.📌(blueButton ↕️= 100)

view.📌((blueButton--orangeButton + 40) ++ (blueButton-=-orangeButton))  //precedence rules require parentheses around constraints that have constants or priorities
orangeButton.📌(orangeButton ↕️= 45 ++ orangeButton ↔️= 25)

complete gist:


  1. I certainly agree that the advantage is purely in readability. typing these would only be feasible with a series of textExpander/Xcode snippets ↩︎
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s