Github url

Cartography

by robb

A declarative Auto Layout DSL for Swift :iphone::triangular_ruler:

7.1K Stars 521 Forks Last release: about 1 year ago (4.0.0) Other 505 Commits 23 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

Cartography :iphone::triangular_ruler:

Using Cartography, you can set up your Auto Layout constraints in declarative code and without any stringly typing!

In short, it allows you to replace this:

addConstraint(NSLayoutConstraint( item: button1, attribute: .Right, relatedBy: .Equal, toItem: button2, attribute: .Left, multiplier: 1.0, constant: -12.0 ))

with this

constrain(button1, button2) { button1, button2 in button1.right == button2.left - 12 }

If you end up using Cartography in production, I'd love to hear from you. You can reach me through Twitter or email.

Installation

CocoaPods

To integrate Cartography into your Xcode project using CocoaPods, specify it in your

Podfile

:

target '<your target name>' do
  pod 'Cartography', '~&gt; 3.0'
end
</your>

Then, run the following command:

$ pod install

Usage

Call the

constrain

function with your

UIView

or

NSView

instances as well as a closure in which you declare the constraints between the different attributes of your views:

constrain(view1, view2) { view1, view2 in view1.width == (view1.superview!.width - 50) \* 0.5 view2.width == view1.width - 50 view1.height == 40 view2.height == view1.height view1.centerX == view1.superview!.centerX view2.centerX == view1.centerX view1.top \>= view1.superview!.top + 20 view2.top == view1.bottom + 20 }

For every view on the left hand side of an equality or inequality operator, Cartography will automatically set its

translatesAutoresizingMaskIntoConstraints

property to

false

.

If the view is not controlled by you–for example _if it belongs to a Apple-provided

UIViewController

class_–you should take appropriate care when declaring its constraints.

Replacing constraints

You can capture multiple constraints in a group to then replace them with new constraints at a later point.

constrain(view) { view in view.width == 100 view.height == 100 } let group = ConstraintGroup() // Attach `view` to the top left corner of its superview constrain(view, replace: group) { view in view.top == view.superview!.top view.left == view.superview!.left } /\* Later \*/ // Move the view to the bottom right corner of its superview constrain(view, replace: group) { view in view.bottom == view.superview!.bottom view.right == view.superview!.right } UIView.animate(withDuration: 0.5, animations: view.layoutIfNeeded)

For convenience, the

constrain

functions also returns

ConstraintGroup

instances:

let group = constrain(button) { button in button.width == 100 button.height == 400 }

Supported attributes

Cartography supports all built-in attributes as of iOS 8 and OS X 10.9, those are:

  • width
  • height
  • top
  • right
  • bottom
  • left
  • leading
  • trailing
  • centerX
  • centerY
  • baseline

as well as the iOS specific

  • firstBaseline
  • leftMargin
  • rightMargin
  • topMargin
  • bottomMargin
  • leadingMargin
  • trailingMargin
  • centerXWithinMargins
  • centerYWithinMargins
  • edgesWithinMargins

These can be further refined using the following operators:

\*

,

/

,

+

and

-

.

Additionally, it supports convenient compound attributes that allow you to assign multiple attributes at once:

constrain(view) { view in view.size == view.superview!.size / 2 view.center == view.superview!.center }
constrain(view) { view in view.edges == inset(view.superview!.edges, 20, 20, 40, 20) }

Aligning multiple view

If you need to align multiple views by a common edge, you can use the

align

functions:

constrain(view1, view2, view3) { view1, view2, view3 in align(top: view1, view2, view3) }

Which is equivalent to

view1.top == view2.top; view2.top == view3.top

. Similar variants exist for

top

,

right
bottom

,

left

,

leading

,

trailing

,

centerX

,

centerY

and

baseline

.

Distributing views evenly

For distributing multiple views, either horizontally or vertically, you can use the

distribute

functions:

constrain(view1, view2, view3) { view1, view2, view3 in distribute(by: 10, horizontally: view1, view2, view3) }

Which is equivalent to

view1.trailing == view2.leading - 10; view2.trailing == view3.leading - 10

.

Setting priorities

You can set the priorities of your constraints using the

~

operator:

constrain(view) { view in view.width \>= 200 ~ UILayoutPriority(100) view.height \>= 200 ~ .required }

Capturing constraints

Since the

==

,

\>=

,

\<=

and

~

emit

NSLayoutConstraint

instances, you can capture their results if you need to refer to the layout constraints at a later time:

var width: NSLayoutConstraint? constrain(view) { view in width = (view.width == 200 ~ 100) }

Note that declaring compound attributes returns multiple constraints at once:

var constraints: [NSLayoutConstraint]? constrain(view) { view in constraints = (view.size == view.superview!.size ~ .defaultLow) }

Documentation

Read the documentation here. For more information, see the gh-pages branch.

Versioning

For Swift 3.x: Versions <= 1.1.0

For Swift 4.x: Versions >= 2.0.0

For Swift 5.x: Versions >= 4.0.0

Support

Please, don't hesitate to file an issue if you have questions.

About Cartography

Cartography was built by Robb Böhnke, is maintained by Orta Therox and was inspired by the excellentFLKAutoLayout by Florian Kugler.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.