Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

robb/Cartography

Repository files navigation

Cartography 📱📐

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', '~> 3.0'
end

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.

* Since Xcode 11 and swift 5.1 the keyword constrain conflicts with the ones used by the CommonUISDK... so, Calling the function with the module name is necessary to make it work properly

e.g.: Cartography.constrain

If you're using it with Xcode 10.3 or earlier, you can still use it as it is, without the module name alongside the function.

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 excellent FLKAutoLayout by Florian Kugler.

About

A declarative Auto Layout DSL for Swift 📱📐

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 49

Languages

AltStyle によって変換されたページ (->オリジナル) /