{"id":1267,"url":"https://github.com/robb/Cartography","last_synced_at":"2025-08-06T13:32:47.453Z","repository":{"id":17955062,"uuid":"20940824","full_name":"robb/Cartography","owner":"robb","description":"A declarative Auto Layout DSL for Swift :iphone::triangular_ruler:","archived":false,"fork":false,"pushed_at":"2023-11-07T11:29:48.000Z","size":1414,"stargazers_count":7337,"open_issues_count":71,"forks_count":526,"subscribers_count":185,"default_branch":"master","last_synced_at":"2025-07-28T13:01:55.241Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2014-06-17T21:54:48.000Z","updated_at":"2025-07-23T02:28:36.000Z","dependencies_parsed_at":"2024-01-29T17:08:22.175Z","dependency_job_id":null,"html_url":"https://github.com/robb/Cartography","commit_stats":{"total_commits":389,"total_committers":57,"mean_commits":6.824561403508772,"dds":0.3676092544987146,"last_synced_commit":"d0dc3f340dec22c96255ca385ff4b9e45fbe9b8e"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/robb/Cartography","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb%2FCartography","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb%2FCartography/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb%2FCartography/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb%2FCartography/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robb","download_url":"https://codeload.github.com/robb/Cartography/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robb%2FCartography/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269022252,"owners_count":24346282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-06T02:00:09.910Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:15:42.559Z","updated_at":"2025-08-06T13:32:46.850Z","avatar_url":"https://github.com/robb.png","language":"Swift","funding_links":[],"categories":["Layout","Libs","Swift","Uncategorized","IOS 或 OSX","Layout [🔝](#readme)"],"sub_categories":["Other Hardware","Layout","Uncategorized","Other free courses","Auto Layout"],"readme":"# Cartography :iphone::triangular_ruler:\n\n\u003ca href=\"https://travis-ci.org/robb/Cartography?branch=master\"\u003e\n    \u003cimg src=\"https://travis-ci.org/robb/Cartography.svg?branch=master\" hspace=\"6px\" align=\"right\" vspace=\"2px\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/Carthage/Carthage/issues/179\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\" align=\"right\" vspace=\"2px\"\u003e\n\u003c/a\u003e\n\nUsing Cartography, you can set up your Auto Layout constraints in declarative code and without any stringly typing!\n\nIn short, it allows you to replace this:\n\n\u003cimg src=\"/images/pirates2.png\" align=\"right\" height=\"280px\" hspace=\"30px\" vspace=\"30px\"\u003e\n\n```Swift\naddConstraint(NSLayoutConstraint(\n    item: button1,\n    attribute: .Right,\n    relatedBy: .Equal,\n    toItem: button2,\n    attribute: .Left,\n    multiplier: 1.0,\n    constant: -12.0\n))\n```\n\nwith this\n\n```Swift\nconstrain(button1, button2) { button1, button2 in\n    button1.right == button2.left - 12\n}\n```\n\nIf you end up using Cartography in production, I'd love to hear from you. You can reach me through [Twitter] or [email].\n\n## Installation\n\n### CocoaPods\n\nTo integrate Cartography into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\ntarget '\u003cYour Target Name\u003e' do\n  pod 'Cartography', '~\u003e 3.0'\nend\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n## Usage\n\nCall the `constrain`_*_ function with your `UIView` or `NSView` instances as well\nas a closure in which you declare the constraints between the different\nattributes of your views:\n\n```swift\nconstrain(view1, view2) { view1, view2 in\n    view1.width   == (view1.superview!.width - 50) * 0.5\n    view2.width   == view1.width - 50\n    view1.height  == 40\n    view2.height  == view1.height\n    view1.centerX == view1.superview!.centerX\n    view2.centerX == view1.centerX\n\n    view1.top \u003e= view1.superview!.top + 20\n    view2.top == view1.bottom + 20\n}\n```\n\n\u003cimg src=\"/images/pirates1.png\" align=\"left\" height=\"220px\" hspace=\"20px\" vspace=\"10px\"\u003e\n\nFor every view on the left hand side of an equality or inequality operator,\nCartography will automatically set its\n`translatesAutoresizingMaskIntoConstraints` property to `false`.\n\nIf the view is\nnot controlled by you–for example _if it belongs to a Apple-provided\n`UIViewController` class_–you should take appropriate care when declaring its\nconstraints.\n\n\u003cbr\u003e\u003cbr\u003e\n\n## Replacing constraints\n\nYou can capture multiple constraints in a group to then replace them with new\nconstraints at a later point.\n\n```swift\nconstrain(view) { view in\n    view.width  == 100\n    view.height == 100\n}\n\nlet group = ConstraintGroup()\n\n// Attach `view` to the top left corner of its superview\nconstrain(view, replace: group) { view in\n    view.top  == view.superview!.top\n    view.left == view.superview!.left\n}\n\n/* Later */\n\n// Move the view to the bottom right corner of its superview\nconstrain(view, replace: group) { view in\n    view.bottom == view.superview!.bottom\n    view.right  == view.superview!.right\n}\n\nUIView.animate(withDuration: 0.5, animations: view.layoutIfNeeded)\n```\n\nFor convenience, the `constrain` functions also returns `ConstraintGroup`\ninstances:\n\n```swift\nlet group = constrain(button) { button in\n    button.width  == 100\n    button.height == 400\n}\n```\n\n## Supported attributes\n\n\nCartography supports all built-in attributes as of iOS 8 and OS X 10.9, those are:\n\n\u003cimg src=\"/images/pirates3.png\" align=\"right\" height=\"400px\" hspace=\"20px\" vspace=\"100px\"\u003e\n\n- `width`\n- `height`\n- `top`\n- `right`\n- `bottom`\n- `left`\n- `leading`\n- `trailing`\n- `centerX`\n- `centerY`\n- `baseline`\n\nas well as the iOS specific\n\n- `firstBaseline`\n- `leftMargin`\n- `rightMargin`\n- `topMargin`\n- `bottomMargin`\n- `leadingMargin`\n- `trailingMargin`\n- `centerXWithinMargins`\n- `centerYWithinMargins`\n- `edgesWithinMargins`\n\nThese can be further refined using the following operators: `*`, `/`, `+` and\n`-`.\n\nAdditionally, it supports convenient compound attributes that allow you to\nassign multiple attributes at once:\n\n```swift\nconstrain(view) { view in\n    view.size   == view.superview!.size / 2\n    view.center == view.superview!.center\n}\n```\n\n```swift\nconstrain(view) { view in\n    view.edges == inset(view.superview!.edges, 20, 20, 40, 20)\n}\n```\n\n### Aligning multiple view\n\nIf you need to align multiple views by a common edge, you can use the `align`\nfunctions:\n\n```swift\nconstrain(view1, view2, view3) { view1, view2, view3 in\n    align(top: view1, view2, view3)\n}\n```\n\nWhich is equivalent to `view1.top == view2.top; view2.top == view3.top`. Similar\nvariants exist for `top`, `right` `bottom`, `left`, `leading`, `trailing`,\n`centerX`, `centerY` and `baseline`.\n\n### Distributing views evenly\n\nFor distributing multiple views, either horizontally or vertically, you can use\nthe `distribute` functions:\n\n```swift\nconstrain(view1, view2, view3) { view1, view2, view3 in\n    distribute(by: 10, horizontally: view1, view2, view3)\n}\n```\n\nWhich is equivalent to `view1.trailing == view2.leading - 10; view2.trailing == view3.leading - 10`.\n\n## Setting priorities\n\nYou can set the priorities of your constraints using the `~` operator:\n\n```swift\nconstrain(view) { view in\n    view.width  \u003e= 200 ~ UILayoutPriority(100)\n    view.height \u003e= 200 ~ .required\n}\n```\n\n## Capturing constraints\n\nSince the `==`, `\u003e=`, `\u003c=` and `~` emit `NSLayoutConstraint` instances, you can\ncapture their results if you need to refer to the layout constraints at a later\ntime:\n\n```swift\nvar width: NSLayoutConstraint?\n\nconstrain(view) { view in\n    width = (view.width == 200 ~ 100)\n}\n```\n\nNote that declaring compound attributes returns multiple constraints at once:\n\n```swift\nvar constraints: [NSLayoutConstraint]?\n\nconstrain(view) { view in\n    constraints = (view.size == view.superview!.size ~ .defaultLow)\n}\n```\n\n## Documentation\n\nRead the documentation [here](http://robb.github.io/Cartography/). For more information, see the [gh-pages](https://github.com/robb/Cartography/tree/gh-pages) branch.\n\n\n\\* 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\n\ne.g.: `Cartography.constrain`\n\nIf 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.\n\n## Versioning\n\nFor *Swift 3.x*: Versions \u003c= 1.1.0\n\nFor *Swift 4.x*: Versions \u003e= 2.0.0\n\nFor *Swift 5.x*: Versions \u003e= 4.0.0\n\n## Support\n\nPlease, don't hesitate to [file an\nissue](https://github.com/robb/Cartography/issues/new) if you have questions.\n\n## About Cartography\n\nCartography was built by [Robb Böhnke][me], is maintained by [Orta Therox][ot] and was inspired by the excellent\n[FLKAutoLayout] by [Florian Kugler][florian].\n\n[flkautolayout]: https://github.com/floriankugler/FLKAutoLayout\n[florian]:       https://github.com/floriankugler\n[me]:            http://robb.is\n[twitter]:       https://twitter.com/dlx\n[email]:         mailto:robb@robb.is\n[ot]:            https://github.com/orta\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobb%2FCartography","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobb%2FCartography","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobb%2FCartography/lists"}