{"id":13489344,"url":"https://github.com/nickynick/Tails","last_synced_at":"2025-03-28T04:31:06.678Z","repository":{"id":18229718,"uuid":"21372286","full_name":"nickynick/Tails","owner":"nickynick","description":"Declarative Auto Layout in Swift, clean and simple","archived":false,"fork":false,"pushed_at":"2014-07-02T20:17:29.000Z","size":204,"stargazers_count":17,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-31T02:33:38.447Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickynick.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-01T02:09:46.000Z","updated_at":"2019-01-31T02:36:04.000Z","dependencies_parsed_at":"2022-09-24T23:02:47.266Z","dependency_job_id":null,"html_url":"https://github.com/nickynick/Tails","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickynick%2FTails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickynick%2FTails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickynick%2FTails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickynick%2FTails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickynick","download_url":"https://codeload.github.com/nickynick/Tails/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245970466,"owners_count":20702422,"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","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-07-31T19:00:23.784Z","updated_at":"2025-03-28T04:31:06.377Z","avatar_url":"https://github.com/nickynick.png","language":"Swift","readme":"# Tails\n\nTails is a take on declarative Auto Layout. If you don't like typing (like me), it might be your kind of thing!\n\nTails is written in Swift and currently supports iOS only. OSX support is coming soon.\n\n## Usage\n\nMeet the *tail operator* (™): `~`. It lets you use your views in fully fledged layout equations. All you need to do is grow them little tails:\n\n```\nTails.install(\n    view1~.top == self.topLayoutGuide~.bottom,\n    view1~.left == view1.superview~,\n    view1~.width == 50,\n\n    view2~.top == view1~,\n    view2~.trailing == view1~.leading + 10,\n    view2~.width \u003e= view1~ * 2\n)\n```\n\nThings become really cool with composite layout attributes:\n\n```\nTails.install(\n    view1~.size == CGSize(width: 60, height: 40),\n    view1~.center == view2~ - CGPoint(x: 0, y: 20),\n\n    view2~.edges == view2.superview~,\n    \n    view3~.top.left.width == view1~\n)\n```\n\n## Attributes\n\nAll `NSLayoutAttribute` values are available in Tails, as such: `left`, `right`, `top`, `bottom`, `leading`, `trailing`, `width`, `height`, `centerX`, `centerY`, `baseline`.\n\nIt is possible to use multiple attributes in the same equation by simply chaining them: `top.left`. There are several predefined composed ones: `size` (`width.height`), `center` (`centerX.centerY.`) and `edges` (`top.left.bottom.right`).\n\nYou may omit right side attributes to infer them from the left side of equation:\n```\nTails.install(\n    headerView~.top.left.right == containerView~\n)\n```\n\n## Constants\n\nLayout constants in Tails are not limited to scalar values. It is possible to use such structs as `CGPoint`, `CGSize` and `UIEdgeInsets`. They only affect specific layout attributes:\n\nConstant               | Attribute\n---------------------- | ---------\n`CGPoint.x`            | `centerX`\n`CGPoint.y`            | `centerY`\n`CGSize.width`         | `width`\n`CGSize.height`        | `height`\n`UIEdgeInsets.top`     | `top`\n`UIEdgeInsets.left`    | `left`\n`-UIEdgeInsets.bottom` | `bottom`\n`-UIEdgeInsets.right`  | `right`\n\nFor instance, this code:\n\n```\nlet insets = UIEdgeInsets(top: 10, left: 20, bottom: 40, right: 20)\n\nTails.install(\n    view~.top.left.right == superview~ + insets,\n    view~.bottom == footerView~.top + insets\n)\n```\n\nIs equivalent to:\n\n```\nTails.install(\n    view~.top == superview~ + 10\n    view~.left == superview~ + 20\n    view~.right == superview~ - 20\n    view~.bottom == footerView~.top - 40\n)\n```\n\n## Priority\n\nUse `~~` operator to specify constraint priority:\n\n```\nTails.install(\n    view1~.width \u003c= view2~ ~~ UILayoutPriorityDefaultLow\n)\n```\n\n## Tips and tricks\n\nFor alignment attributes, you may omit the right side view to refer to the left superview:\n\n```\nlet insets = UIEdgeInsets(...)\n\nTails.install(\n    view~.edges == insets\n    // same as view~.edges == view.superview~.edges + insets\n)\n```\n\n## Coming soon\n\n- OSX support\n- Tests (yeah, I know)\n- More examples\n- Constraint manipulation\n- Kitties\n\n## About\n\nTails shamelessly borrows many ideas from the wonderful [Masonry](https://github.com/Masonry/Masonry) by [Jonas Budelmann](https://github.com/cloudkite).\n\nIf you like Auto Layout DSL, you might also want to try [Cartography](https://github.com/robb/Cartography) by [Robert Böhnke](https://github.com/robb).\n","funding_links":[],"categories":["Libs"],"sub_categories":["Layout","Auto Layout"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickynick%2FTails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickynick%2FTails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickynick%2FTails/lists"}