{"id":15773971,"url":"https://github.com/lurado/ldolayouttemplates","last_synced_at":"2025-03-14T05:32:15.139Z","repository":{"id":56918329,"uuid":"84930072","full_name":"lurado/LDOLayoutTemplates","owner":"lurado","description":"Manage different iOS screen layouts with ease","archived":false,"fork":false,"pushed_at":"2018-10-20T12:26:03.000Z","size":49195,"stargazers_count":4,"open_issues_count":2,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-11T16:13:26.511Z","etag":null,"topics":["autolayout","cocoapod","interface-builder","ios","objective-c","swift"],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","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/lurado.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":"2017-03-14T09:26:24.000Z","updated_at":"2019-12-17T19:11:32.000Z","dependencies_parsed_at":"2022-08-21T03:50:51.259Z","dependency_job_id":null,"html_url":"https://github.com/lurado/LDOLayoutTemplates","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lurado%2FLDOLayoutTemplates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lurado%2FLDOLayoutTemplates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lurado%2FLDOLayoutTemplates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lurado%2FLDOLayoutTemplates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lurado","download_url":"https://codeload.github.com/lurado/LDOLayoutTemplates/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243532517,"owners_count":20306151,"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":["autolayout","cocoapod","interface-builder","ios","objective-c","swift"],"created_at":"2024-10-04T16:04:16.550Z","updated_at":"2025-03-14T05:32:11.709Z","avatar_url":"https://github.com/lurado.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LDOLayoutTemplates\n\nDesign multiple layouts of the same view in Interface Builder, and easily transition between them.\n\n[![Version](https://img.shields.io/cocoapods/v/LDOLayoutTemplates.svg?style=flat)](https://cocoapods.org/pods/LDOLayoutTemplates)\n[![License](https://img.shields.io/cocoapods/l/LDOLayoutTemplates.svg?style=flat)](https://cocoapods.org/pods/LDOLayoutTemplates)\n[![Platform](https://img.shields.io/cocoapods/p/LDOLayoutTemplates.svg?style=flat)](https://cocoapods.org/pods/LDOLayoutTemplates)\n\n**LDOLayoutTemplates lets you achieve this…**\n\n![Dashboard demo transitions](Screenshots/DashboardExample.gif)\n\n**…with very little code:**\n\n```swift\nclass DashboardViewController: UIViewController {\n    @IBOutlet weak var portraitLargeListLayout: LDOLayoutTemplate!\n    @IBOutlet weak var landscapeLargeListLayout: LDOLayoutTemplate!\n    private var defaultLayout: LDOLayoutTemplate!\n    private var largeListLayoutActive = false\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // Create a backup of the initial view contents for later restoration.\n        defaultLayout = LDOLayoutTemplate(withCurrentStateForViewsIn: portraitLargeListLayout)\n    }\n    \n    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n        super.viewWillTransition(to: size, with: coordinator)\n        \n        coordinator.animate(alongsideTransition: { _ in\n            self.applyLayout(for: size)\n        })\n    }\n    \n    @IBAction func toggleLargeListLayout() {\n        largeListLayoutActive.toggle()\n        \n        view.layoutIfNeeded()\n        UIView.animate(withDuration: 0.3) {\n            self.applyLayout(for: self.view.bounds.size)\n        }\n    }\n    \n    private func applyLayout(for size: CGSize) {\n        if largeListLayoutActive {\n            if size.width \u003e size.height {\n                landscapeLargeListLayout.apply()\n            } else {\n                portraitLargeListLayout.apply()\n            }\n        } else {\n            defaultLayout.apply()\n        }\n        view.layoutIfNeeded()\n    }\n}\n```\n\nThe different constraints and attributes of each view are defined by three views in the storyboard:\n\n![Storyboard](Screenshots/Storyboard.png)\n\n## Motivation\n\nWe love visually creating our views in Interface Builder.\nHowever, if a screen layout differs between orientations, or if a view has two modes (e.g. large and collapsed modes), setting up constraints and managing them in code quickly turns into a mess.\nThings only get worse if you have more than two variations.\n\nWouldn't it be nice to design each layout separately, with an easy way to transition from one to another? \n\n## Example\n\nTo run the example project, clone the repo, open the workspace in the `Example` folder, and click Run.\nAlternatively, you can use `pod try https://github.com/lurado/LDOLayoutTemplates`. \n\nThe dashboard example shown above is only available on iPad.\n\n## How To\n\n1. In a storyboard, lay out your view controller's view as usual — let's assume this will be used in landscape orientation.\n1. Drag a *View* object from the library onto your view controller scene in the left sidebar, outside of its view hierarchy.\n    Change its *Custom Class* to `LDOLayoutTemplate` in the right sidebar.\n    \n    This is your layout template in which you design the variation (e.g. portrait orientation).\n    This view will never be shown to the user, but its constraints (and attributes, see below) will be transferred to the main view.\n1. Change the size of your template view to portrait dimensions (not really necessary, but it makes designing it easier).\n1. Copy or re-create the views whose constraints change between layouts from the view controller's view to the template view.\n    If you copy your views, make sure to disconnect any outlets.\n1. Modify the constraints as needed.\n1. Connect the `targetView` outlet of each template view to its corresponding view in the view controller's view.\n    It is important that every template view participating in a constraint has this outlet connected.\n1. Add and connect an outlet for the `LDOLayoutTemplate` to your view controller.\n1. Call `apply` on the template to switch to this layout, for example on orientation change. \n    If you want to animate the transition, wrap the call to `apply` in an `UIView` animation block.\n1. If you plan to switch back to your original layout, create another instance of `LDOLayoutTemplate` (typically in `viewDidLoad`, as shown in the example code above).\n    Initialize this layout using `LDOLayoutTemplate.init(withCurrentStateForViewsIn:)`, which creates an `LDOLayoutTemplate` based on the current view configuration.\n    Call `apply` on this template to restore the initial state of the view.\n1. Setup as many templates as you need, and happily switch between them.\n\n## Attribute Changes\n\nBy default, `LDOLayoutTemplate` only copies Auto Layout constraints from one view to another.\nYou can also transfer attributes from each view in a template to its `targetView` by either adding a comma separated list of attributes to *Template Attributes* in the Attribute Inspector in Interface Builder,\nor by overriding `transferredTemplateAttributeKeyPaths` in your `UIView` subclass.\n\n## Limitations\n\nLayout guides such as the Safe Area are not supported.\nUse helper views anchored to the layout guide instead.\n\n## Installation\n\nLDOLayoutTemplates is available through [CocoaPods](https://cocoapods.org).\nTo install it, add the following line to your Podfile:\n\n```ruby\npod \"LDOLayoutTemplates\"\n```\n\n## How Does It Work?\n\nThis library is actually quite simple, and uses the following approach:\n\n- Iterate over all views of a template and collect all constraints between views with a target view.\n  These are the constraints that will be _activated_ when `apply` is called.\n- Iterate over all the target views (the ones in your view controller's view having a `targetView` outlet \n    pointing at them), and collect all constraints between them.\n  These constraints will be _deactivated_ when `apply` is called.\n- The algorithm considers all constraints that are either set up *between* two views with a target view, or which define  width and height constraints for a view with a target view.\n\n## Author\n\nRaschke \u0026 Ludwig GbR, https://www.lurado.com/\n\n## License\n\nLDOLayoutTemplates is available under the MIT license.\nSee the [LICENSE](LICENSE) file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flurado%2Fldolayouttemplates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flurado%2Fldolayouttemplates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flurado%2Fldolayouttemplates/lists"}