{"id":21437600,"url":"https://github.com/gabrieltheodoropoulos/gteasylayout","last_synced_at":"2026-05-15T13:07:30.302Z","repository":{"id":56912409,"uuid":"188982309","full_name":"gabrieltheodoropoulos/GTEasyLayout","owner":"gabrieltheodoropoulos","description":"GTEasyLayout minimizes the effort of setting up constraints programmatically, as it achieves that with one line of code only! Not recommended for specifying too complicated constraints (yet!).","archived":false,"fork":false,"pushed_at":"2019-05-30T09:39:09.000Z","size":32,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-04T09:06:29.935Z","etag":null,"topics":["autolayout","constraint-layout","constraints","custom-types","protocol","ui","uiview"],"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/gabrieltheodoropoulos.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":"2019-05-28T08:00:16.000Z","updated_at":"2022-10-12T02:53:28.000Z","dependencies_parsed_at":"2022-08-21T03:20:13.358Z","dependency_job_id":null,"html_url":"https://github.com/gabrieltheodoropoulos/GTEasyLayout","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/gabrieltheodoropoulos/GTEasyLayout","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieltheodoropoulos%2FGTEasyLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieltheodoropoulos%2FGTEasyLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieltheodoropoulos%2FGTEasyLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieltheodoropoulos%2FGTEasyLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrieltheodoropoulos","download_url":"https://codeload.github.com/gabrieltheodoropoulos/GTEasyLayout/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieltheodoropoulos%2FGTEasyLayout/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33067521,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["autolayout","constraint-layout","constraints","custom-types","protocol","ui","uiview"],"created_at":"2024-11-23T00:27:44.198Z","updated_at":"2026-05-15T13:07:30.282Z","avatar_url":"https://github.com/gabrieltheodoropoulos.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GTEasyLayout\n\n![Platform](https://img.shields.io/cocoapods/p/GTEasyLayout.svg)\n![Language](https://img.shields.io/github/languages/top/gabrieltheodoropoulos/GTEasyLayout.svg?color=orange)\n![License](https://img.shields.io/github/license/gabrieltheodoropoulos/GTEasyLayout.svg)\n![Version](https://img.shields.io/cocoapods/v/GTEasyLayout.svg)\n\n## What is GTEasyLayout?\n\n*GTEasyLayout* is a small framework written in Swift which aims to *minimise the effort of setting up constraints programmatically when implementing UI in iOS apps*. It's the perfect tool to use when constraints are not extremely complicated and typing a bunch of similar lines for multiple views becomes tiring and anti-productive.\n\nGTEasyLayout is composed by:\n\n1. The `GTEasyLayoutAdaptable` Swift **protocol** which defines methods that automate the constraint configuration process. An extension with default implementation is included so the aimed functionality exists instantly and out of the box.\n2. The `GTEasyLayout` class which is just a *namespace for custom defined types*. There should not be created instances of this class as there are not any available properties or methods to access.\n\nThe main idea behind the current implementation is that *a subview snaps to all or some of the edges of the container view*. It's possible to *specify spacing (padding)* between the subview and the container view on any side, to *provide the size of the view*, as well as to *animate changes to the padding and size dimensions* (meaning to change the constraints that control the position and size of the subview animated).\n\nHere is the protocol definition:\n\n```swift\npublic protocol GTEasyLayoutAdaptable {\n\n    func add(view: UIView, to targetView: UIView, snapTo edges: GTEasyLayout.SnapEdges, padding: UIEdgeInsets, size: CGSize)\n\n    func updatePadding(at side: GTEasyLayout.Side, ofView view: UIView, newValue: CGFloat, animationSettings: GTEasyLayout.AnimationSettings?, completion: (()-\u003e Void)?)\n\n    func updateDimension(_ dimension: GTEasyLayout.Dimension, ofView view: UIView, newValue: CGFloat, animationSettings: GTEasyLayout.AnimationSettings?, completion: (() -\u003e Void)?)\n}\n```\n\nSee the *GTEasyLayout.swift* file for documentation on the custom types appearing above and the *GTEasyLayoutAdaptable.swift* for documentation regarding each method. You can find all that at this [generated documentation](https://gtiapps.com/docs/gteasylayout/index.html) by [jazzy](https://github.com/realm/jazzy).\n\n---\n\n## Integration\n\nGTEasyLayout can be integrated into a project in two different ways:\n\n### Using CocoaPods\n\nIn your Podfile add:\n\n```ruby\npod 'GTEasyLayout'\n```\n\nRemember to *import* the framework anywhere you are about to use it:\n\n```swift\nimport GTEasyLayout\n```\n\n### Manually\n\nDownload or clone this repository, then add the *Source* directory along with the two contained files into your project.\n\n---\n\n## Usage Examples\n\n**Note:** *See the [wiki](https://github.com/gabrieltheodoropoulos/GTEasyLayout/wiki) for detailed examples along with visual representation of the results, or open the sample project in Xcode to see everything in action.*\n\nFirst, make your class conform to the `GTEasyLayoutAdaptable` protocol:\n\n```swift\nclass ViewController: UIViewController, GTEasyLayoutAdaptable {\n    ...\n}\n```\n\nInto the point now:\n\n**Snap a subview to all edges** of the view controller's root view leaving 50px padding from all sides:\n\n```swift\nadd(view: someView,\n    to: self.view,\n    snapTo: .all,\n    padding: UIEdgeInsets(all: 50.0),\n    size: .zero)\n```\n\n**Snap to top, left, bottom and set the width to 250px**. Height will be 0.0, as it's calculated automatically:\n\n```swift\nadd(view: myView,\n    to: self.view,\n    snapTo: .topLeftBottom,\n    padding: UIEdgeInsets(top: 20.0, left: 0.0, bottom: 0.0, right: 0.0),\n    size: CGSize(width: 250.0, height: 0.0))\n```\n\n**Center both horizontally and vertically** a view with size 200x150px:\n\n```swift\nadd(view: someView,\n    to: self.view,\n    snapTo: .centerX_Y,\n    padding: .zero,\n    size: CGSize(width: 200.0, height: 150.0))\n```\n\n**Updating the padding on the left side animated**:\n\n```swift\nlet animSettings = GTEasyLayout.AnimationSettings(withDuration: 0.5, delay: 0.0, damping: 0.7, velocity: 1.0, options: .curveLinear)\n\nupdatePadding(at: .left,\n              ofView: someView,\n              newValue: 150.0,\n              animationSettings: animSettings,\n              completion: nil)\n```\n\n**Animating the change of the height dimension** (passing `nil` to `animationSettings` will make the following method use default animation settings):\n\n```swift\nupdateDimension(.height,\n                ofView: someView,\n                newValue: 400.0,\n                animationSettings: nil,\n                completion: nil)\n```\n\nIf you don't want to animate changes on constraints, then initialize a `GTEasyLayout.AnimationSettings` object and set the `duration` to zero.\n\n---\n\n## Other Notes\n\nGTEasyLayout is a work in progress, and new functionalities will be added over the course of time.\n\nCreated with ❤️ by [Gabriel Theodoropoulos](https://gtiapps.com) (gabrielth.devel@gmail.com) and it is provided under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieltheodoropoulos%2Fgteasylayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrieltheodoropoulos%2Fgteasylayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieltheodoropoulos%2Fgteasylayout/lists"}