• Stars
    star
    7,338
  • Rank 5,275 (Top 0.2 %)
  • Language
    Swift
  • License
    Other
  • Created over 10 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A declarative Auto Layout DSL for Swift 📱📐

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.

More Repositories

1

hamburger-button

A hamburger button transition
Swift
2,308
star
2

RBBAnimation

Block-based animations made easy, comes with easing functions and a CASpringAnimation replacement.
Objective-C
2,061
star
3

Underscore.m

A DSL for Data Manipulation
Objective-C
1,465
star
4

FLXView

A UIView that uses Flexbox for layouting. ✨
Objective-C
481
star
5

Swim

A DSL for writing HTML in Swift
Swift
310
star
6

Asterism

Asterism is yet another functional toolbelt for Objective-C. It tries to be typesafe and simple.
Objective-C
226
star
7

RBBJSON

Flexible JSON traversal for rapid prototyping.
Swift
164
star
8

Fantastical-Alfred-Workflow

A simple Alfred 2 workflow for Fantastical.
158
star
9

NES.swift

An NES emulator written in Swift
Swift
149
star
10

dotfiles

Dotfiles to make computing personal.
Shell
87
star
11

Stubbilino

Simple stubbing for Objective-C
Objective-C
86
star
12

swamp

icon stamping in Swift
Swift
85
star
13

Peel-Off-Animation-Example-Code

Example code for https://robb.is/working-on/a-peel-off-animation
Swift
62
star
14

Monocle

Pretty much only a Lens
Swift
45
star
15

ShaderBugs

Some isssues I ran into with SwiftUI.Shader
Swift
36
star
16

robb.swift

My personal website ported to Swift
Swift
34
star
17

Xcode-Configurations

Useful tweaks to Xcode
Objective-C
30
star
18

jekyll-embedly-client

No longer maintained
Ruby
23
star
19

URLRequest-AWS

An extension on URLRequest to sign it for AWS.
Swift
20
star
20

Marbleo.us

A marbleous project
CoffeeScript
18
star
21

Digitale-Zivilgesellschaft

Recommendations from multiple civil society organisations that fight for independent digital infrastructure and open access to knowledge.
HTML
11
star
22

laughing-man

The Laughing Man logo implemented in pure HTML/CSS
6
star
23

monome.js

A library for writing monome apps with node.js
C++
5
star
24

slang

The pxl effect in the browser
CoffeeScript
4
star
25

spinamp

Winamp inside Spotify – it really whips the moose's ass
CoffeeScript
2
star
26

FeedImporter

Import RSS feeds into SoundCloud
Ruby
1
star
27

thedickensbar.com

Put a Dickensbar on top of every page. Lost all its meaning now that the dickbar is gone…
CSS
1
star
28

6strings

Guitar synthesis in the browser!
CoffeeScript
1
star
29

Future

A simple, cold Future.
Swift
1
star