{"id":1272,"url":"https://github.com/isair/ManualLayout","last_synced_at":"2025-07-30T20:32:56.499Z","repository":{"id":27738955,"uuid":"31226686","full_name":"isair/ManualLayout","owner":"isair","description":"✂  Easy to use and flexible library for manually laying out views and layers for iOS and tvOS. Supports AsyncDisplayKit.","archived":false,"fork":false,"pushed_at":"2020-04-23T14:57:56.000Z","size":134,"stargazers_count":280,"open_issues_count":7,"forks_count":15,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-09-23T06:45:54.112Z","etag":null,"topics":["cocoapods","edges","layout","layout-engine","position","swift","uiviewcontroller-properties"],"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/isair.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":"2015-02-23T19:59:23.000Z","updated_at":"2024-09-11T12:09:14.000Z","dependencies_parsed_at":"2022-09-08T20:51:11.756Z","dependency_job_id":null,"html_url":"https://github.com/isair/ManualLayout","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isair%2FManualLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isair%2FManualLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isair%2FManualLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isair%2FManualLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/isair","download_url":"https://codeload.github.com/isair/ManualLayout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228187611,"owners_count":17882335,"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":["cocoapods","edges","layout","layout-engine","position","swift","uiviewcontroller-properties"],"created_at":"2024-01-05T20:15:42.664Z","updated_at":"2024-12-04T20:31:10.492Z","avatar_url":"https://github.com/isair.png","language":"Swift","readme":"ManualLayout [![CocoaPods](https://img.shields.io/cocoapods/l/ManualLayout.svg)](https://github.com/isair/ManualLayout/blob/master/LICENSE) ![CocoaPods](https://img.shields.io/cocoapods/p/ManualLayout.svg)\n-----\n\n[![Build Status](https://travis-ci.org/isair/ManualLayout.svg)](https://travis-ci.org/isair/ManualLayout)\n[![CocoaPods](https://img.shields.io/cocoapods/v/ManualLayout.svg)](https://cocoapods.org/pods/ManualLayout)\n[![Gitter](https://badges.gitter.im/JOINCHAT.svg)](https://gitter.im/isair/ManualLayout?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n\u003ca target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/aHZuH6shEL9HHDhoj4sgJJga/isair/ManualLayout'\u003e\n  \u003cimg alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/aHZuH6shEL9HHDhoj4sgJJga/isair/ManualLayout.svg' /\u003e\n\u003c/a\u003e\n\n# Table of Contents\n\n1. [Installation](#installation)\n2. [Usage](#usage)\n3. [API Cheat Sheet](#api-cheat-sheet)\n\n# Installation\n\n### [Carthage](https://github.com/Carthage/Carthage#installing-carthage)\n\nAdd the following line to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile).\n\n```\ngithub \"isair/ManualLayout\"\n```\n\nThen do `carthage update`. After that, add the framework to your project.\n\n### [CocoaPods](https://github.com/CocoaPods/CocoaPods)\n\nAdd the following line in your `Podfile`.\n\n```\npod \"ManualLayout\"\n```\t\n\n# Usage\n\nJust `import ManualLayout` in your code and use the methods and properties provided by the library to layout your views. You can check out the cheat sheet below for a compact list of everything. There are also [example projects](https://github.com/isair/ManualLayout/tree/master/Examples) to get you started.\n\n\n# API Cheat Sheet\n\n### Smart Assign Operator\n\nThe smart assign operator `=~` has only one job; to make your life easier.\n\n```swift\nsomeView.origin =~ (0, 20)\nanotherView.size =~ (100, 100)\nyetAnotherView.frame =~ (0, 120, view.width, 100)\n```\n\n### CGRect/CALayer/UIView Properties\n\n```swift\n// For fast positioning.\nvar origin: CGPoint\nvar x: CGFloat \nvar y: CGFloat\nvar center: CGPoint\nvar centerX: CGFloat\nvar centerY: CGFloat\nvar top: CGFloat\nvar right: CGFloat\nvar bottom: CGFloat\nvar left: CGFloat\n\n// For fast sizing.\nvar size: CGSize\nvar width: CGFloat\nvar height: CGFloat\n\n// Alternate edges. Their names may change in the near future.\nvar top2: CGFloat\nvar right2: CGFloat\nvar bottom2: CGFloat\nvar left2: CGFloat\n```\n\nThe difference between alternate edges and normal edges require a bit of explaining. Imagine we have a view at position (0, 0) of size (100, 100) named *myView*. If we do `myView.right = 200`, then its position is now (100, 0) and its size remains unchaged. However, back when our view was located at (0, 0), if we had done `myView.right2 = 200`, then *myView* would have still been at (0, 0) but would have had a size of (200, 100).\n\nSo basically, *setting a normal edge's position drags the whole view along with that edge but setting an alternative edge's position drags just that edge*. And don't worry if you, for example, try to drag a left edge past its view's right edge. Edge swapping is done automatically so you don't have to worry about it.\n\n### UIView Methods\n\nJust one method with two variants for now, and those are used for easy size calculations.\n\n```swift\nfunc sizeToFit(width: CGFloat, height: CGFloat) -\u003e CGSize\nfunc sizeToFit(constrainedSize: CGSize) -\u003e CGSize\n```\n\nSo let's say that you have a label inside a view and you want to lay it out with an inset of 4 points on all sides, you could easily do the following:\n\n```swift\nmyLabel.sizeToFit(inset(myView.size, 4))\nmyLabel.origin =~ (4, 4)\n```\n\nDone!\n\n### UIScrollView Properties\n\n```swift\nvar contentWidth: CGFloat\nvar contentHeight: CGFloat\n\nvar contentTop: CGFloat // Always equal to 0. Read-only.\nvar contentLeft: CGFloat // Always equal to 0. Read-only.\nvar contentBottom: CGFloat // contentHeight alias.\nvar contentRight: CGFloat // contentWidth alias.\n\nvar viewportTop: CGFloat // contentOffset.y alias.\nvar viewportLeft: CGFloat // contentOffset.x alias.\nvar viewportBottom: CGFloat // conentOffset.y + view height\nvar viewportRight: CGFloat // contentOffset.x + view width\n```\n\n### UIViewController Properties\n\nAll UIViewController properties are read only. They offer easy read access to a controller's view's properties.\n\n```swift\nvar bounds: CGRect\n\nvar center: CGPoint\nvar centerX: CGFloat\nvar centerY: CGFloat\n\nvar size: CGSize\nvar width: CGFloat\nvar height: CGFloat\n\nvar top: CGFloat // Top layout guide y coordinate.\nvar right: CGFloat // Equal to the width of the controller's view.\nvar bottom: CGFloat // Bottom layout guide y coordinate.\nvar left: CGFloat // Always equal to 0.\n```\n\n### Helper Methods\n\nThese functions never modify the view/layer/rectangle/etc they are passed.\n\n```swift\nfunc inset(view: UIView, amount: CGFloat) -\u003e CGRect\nfunc inset(layer: CALayer, amount: CGFloat) -\u003e CGRect\nfunc inset(rect: CGRect, amount: CGFloat) -\u003e CGRect\n\nfunc inset(view: UIView, dx: CGFloat, dy: CGFloat) -\u003e CGRect\nfunc inset(layer: CALayer, dx: CGFloat, dy: CGFloat) -\u003e CGRect\nfunc inset(rect: CGRect, dx: CGFloat, dy: CGFloat) -\u003e CGRect\n\nfunc inset(view: UIView, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -\u003e CGRect\nfunc inset(layer: CALayer, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -\u003e CGRect\nfunc inset(rect: CGRect, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -\u003e CGRect\n\nfunc inset(size: CGSize, amount: CGFloat) -\u003e CGSize\nfunc inset(size: CGSize, dx: CGFloat, dy: CGFloat) -\u003e CGSize\nfunc inset(size: CGSize, top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -\u003e CGSize\n```\n\n```swift\nfunc offset(view: UIView, amount: CGFloat) -\u003e CGRect\nfunc offset(layer: CALayer, amount: CGFloat) -\u003e CGRect\nfunc offset(rect: CGRect, amount: CGFloat) -\u003e CGRect\n\nfunc offset(view: UIView, dx: CGFloat, dy: CGFloat) -\u003e CGRect\nfunc offset(layer: CALayer, dx: CGFloat, dy: CGFloat) -\u003e CGRect\nfunc offset(rect: CGRect, dx: CGFloat, dy: CGFloat) -\u003e CGRect\n\nfunc offset(point: CGPoint, amount: CGFloat) -\u003e CGPoint\nfunc offset(point: CGPoint, dx: CGFloat, dy: CGFloat) -\u003e CGPoint\n```\n","funding_links":[],"categories":["Layout","Libs"],"sub_categories":["Other Hardware","Layout","Other free courses"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisair%2FManualLayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fisair%2FManualLayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisair%2FManualLayout/lists"}