{"id":1290,"url":"https://github.com/Otbivnoe/Framezilla","last_synced_at":"2025-07-30T20:33:06.485Z","repository":{"id":49915015,"uuid":"66377720","full_name":"Otbivnoe/Framezilla","owner":"Otbivnoe","description":"Elegant library that wraps working with frames with a nice chaining syntax.","archived":true,"fork":false,"pushed_at":"2021-06-08T10:39:38.000Z","size":391,"stargazers_count":132,"open_issues_count":1,"forks_count":13,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-28T10:42:39.175Z","etag":null,"topics":["ios","layout","swift"],"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/Otbivnoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-23T15:08:05.000Z","updated_at":"2023-09-13T14:45:59.000Z","dependencies_parsed_at":"2022-08-21T03:20:09.331Z","dependency_job_id":null,"html_url":"https://github.com/Otbivnoe/Framezilla","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Otbivnoe%2FFramezilla","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Otbivnoe%2FFramezilla/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Otbivnoe%2FFramezilla/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Otbivnoe%2FFramezilla/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Otbivnoe","download_url":"https://codeload.github.com/Otbivnoe/Framezilla/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228187629,"owners_count":17882338,"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":["ios","layout","swift"],"created_at":"2024-01-05T20:15:43.067Z","updated_at":"2024-12-04T20:31:16.590Z","avatar_url":"https://github.com/Otbivnoe.png","language":"Swift","funding_links":[],"categories":["Layout"],"sub_categories":["Other Hardware","Other free courses"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"img/framezilla_green.png\" alt=\"Framezilla\"/\u003e\n\u003c/p\u003e\n\n[![Build Status](https://travis-ci.org/Otbivnoe/Framezilla.svg?branch=master)](https://travis-ci.org/Otbivnoe/Framezilla)\n[![Version](https://img.shields.io/cocoapods/v/Framezilla.svg?style=flat)](http://cocoadocs.org/docsets/Framezilla)\n[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![Platform](https://img.shields.io/cocoapods/p/Framezilla.svg?style=flat)](http://cocoadocs.org/docsets/Framezilla)\n![Swift 4.0](https://img.shields.io/badge/Swift-4.0-orange.svg)\n[![License](https://img.shields.io/cocoapods/l/Framezilla.svg?style=flat)](http://cocoadocs.org/docsets/Framezilla)\n\n**Everyone wants to see smooth scrolling, that tableview or collectionview scrolls without any lags and it's right choice. But the constraints do not give it for us. Therefore, we have to choose manual calculation frames, but sometimes, when cell has a complex structure, code has not elegant, beautiful structure.**\n\n**So, it's library for those, who want to see smooth scrolling with elegant code under the hood!**\n\n#**Enjoy reading!** :tada:\n\n**Framezilla** is the child of [Framer](https://github.com/Otbivnoe/Framer) (analog of great layout framework which wraps manually calculation frames with a nice-chaining syntax), but only for Swift.\n\n# Installation :fire:\n\n### CocoaPods\n\n[CocoaPods](http://cocoapods.org) is a dependency manager for Swift and Objective-C Cocoa projects. It has over eighteen thousand libraries and can help you scale your projects elegantly. You can install it with the following command:\n\n```bash\n$ sudo gem install cocoapods\n```\n\nTo integrate Framezilla, simply add the following line to your `Podfile`:\n\n```ruby\npod \"Framezilla\"\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.\n\nYou can install Carthage with [Homebrew](http://brew.sh/) using the following command:\n\n```bash\n$ brew update\n$ brew install carthage\n```\nTo integrate Framezilla into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n```ogdl\ngithub \"Otbivnoe/Framezilla\"\n```\n\nRun `carthage update` to build the framework and drag the built `Framezilla.framework` into your Xcode project.\n\n# Features :boom:\n\n- [x] Edges with superview\n- [x] Width / Height\n- [x] Top / Left / Bottom / Right \n- [x] CenterX / CenterY / Center (between views)\n- [x] SizeToFit / SizeThatFits / WidthToFit / HeightToFit\n- [x] Container\n- [x] Stack\n- [x] Optional semantic - `and`\n- [x] Side relations: `nui_left`, `nui_bottom`, `nui_width`, `nui_centerX` and so on.\n- [x] States\n- [x] Safe area support 😱\n\n# Usage :rocket:\n\n### Size (width, height)\n\nThere're a few methods for working with view's size.\n\nYou can configure ```width``` and ```height``` separately:\n\n```swift\nview.configureFrame { maker in\n    maker.width(200).and.height(200)\n}\n```\n\nor together with the same result: \n\n```swift\nview.configureFrame { maker in\n    maker.size(width: 200, height: 200)\n}\n```\nAlso in some cases you want to equate the sides of two views with some multiplier.\n\nFor example:\n\n```swift\nview.configureFrame { maker in\n    maker.width(to: view1.nui_height, multiplier: 0.5)\n    maker.height(to: view1.nui_width) // x1 multiplier - default\n}\n```\n\n## Edges\n\nFramezilla has two method for comfortable creating edge-relation.\n\n![](img/edges.png)\n\nEither you can create edge relation so\n\n```swift\nview.configureFrame { maker in\n    maker.edges(insets: UIEdgeInsetsMake(5, 5, 5, 5)) // UIEdgeInsets.zero - default\n}\n```\n\nor\n\n```swift\nview.configureFrame { maker in\n    maker.edges(top: 5, left: 5, bottom: 5, right: 5)\n}\n```\nthe second method has optional parameters, so ```maker.edges(top: 5, left: 5, bottom: 5)``` also works correct, but does not create ```right``` relation, that in some cases is very useful.\n\n## Side relations (Top, left, bottom, right)\n\nYou can create edge relation, as shown above, but only use side relations.\n\n```swift\nview.configureFrame { maker in\n    maker.top(inset: 5).and.bottom(inset: 5)\n    maker.left(inset: 5).and.right(inset: 5)\n}\n```\n\nAlso possible to create relations with another view, not a superview:\n\n![](img/bottomLeftRelation.png)\n\n```swift\n// Red view\nview.configureFrame { maker in\n    maker.size(width: 30, height: 30)\n    maker.left(to: self.view1.nui_right, inset: 5)\n    maker.bottom(to: self.view1.nui_centerY)\n}\n```\n\nIn iOS 11 Apple has introduced the safe area, similar to `topLayoutGuide` and `bottomLayoutGuide`. Framezilla supports this new api as well:\n\n```swift\ncontent.configureFrame { maker in\n    maker.top(to: nui_safeArea)\n    maker.bottom(to: nui_safeArea)\n    maker.right(to: nui_safeArea, inset: 10)\n    maker.left(to: nui_safeArea, inset: 10)\n}\n```\n\n\u003cimg src=\"img/safe_area.png\" width=\"260\"\u003e\n\n**Note**: In earlier versions of OS than iOS 11, these methods create a relation to a superview, not the safe area.\n\n## Center relations\n\nIf you just want to center subview relative superview with constant `width` and `height`, this approach specially for you:\n\n```swift\nview.configureFrame { maker in\n    maker.centerY().and.centerX()\n    maker.size(width: 100, height: 100)\n}\n```\n\nAlso possible to set manually centerX and centerY. Just call ```setCenterX``` and ```setCenterY```.\n\nWhat if you want to join the center point of the view with the top right point of another view? \n\n### PFF, OKAY.\n\n![](img/centered.png)\n\n```swift\nview.configureFrame { maker in\n    maker.centerX(to: self.view1.nui_right, offset: 0)\n    maker.centerY(to: self.view1.nui_top) //Zero offset - default\n    maker.size(width: 50, height: 50)\n}\n```\n\n## SizeToFit and SizeThatFits\n\nVery often you should configure labels, so there are some methods for comfortable work with them.\n\n#### SizeToFit\n\n![](img/sizeToFit.png)\n\n```swift\nlabel.configureFrame { maker in\n    maker.sizeToFit() // Configure width and height by text length no limits\n    maker.centerX().and.centerY()\n}\n```\n\n#### SizeThatFits\n\nBut what if you have to specify edges for label?\n\n![](img/sizeThatFits.png)\n\n```swift\nlabel.configureFrame { maker in\n    maker.sizeThatFits(size: CGSize(width: 200, height: 100))\n    maker.centerX().and.centerY()\n}\n```\n\n## Container\n\nUse this method when you want to calculate a `width` and `height` by wrapping all subviews. \n\nYou can also specify a special container relation:\n\n```swift\npublic enum ContainerRelation {\n    case width(Number)\n    case height(Number)\n    case horizontal(left: Number, right: Number)\n    case vertical(top: Number, bottom: Number)\n}\n```\n\nFor instance, if you set a width for a container, only a dynamic height will be calculated.\n\n### NOTE:\n\n**It atomatically adds all subviews to the container. Don't add subviews manually.**\n\n**If you don't use a static width for instance, important to understand, that it's not correct to call `left` and `right` relations together by subviews, because `container` sets width relatively width of subviews and here is some ambiguous.**\n\n![](img/container.png)\n\n```swift\nlet container = [content1, content2, content3, content4].container(in: view, relation: /* if needed */) {\n    content1.configureFrame { maker in\n        maker.centerX()\n        maker.top()\n        maker.size(width: 50, height: 50)\n    }\n\n    content2.configureFrame { maker in\n        maker.top(to: content1.nui_bottom, inset: 5)\n        maker.left()\n        maker.size(width: 80, height: 80)\n    }\n\n    content3.configureFrame { maker in\n        maker.top(to: content1.nui_bottom, inset: 15)\n        maker.left(to: content2.nui_right, inset: 5)\n        maker.size(width: 80, height: 80)\n    }\n\n    content4.configureFrame { maker in\n        maker.top(to: content3.nui_bottom, inset: 5)\n        maker.right()\n        maker.size(width: 20, height: 20)\n    }\n}\n\n// width and height are already configured\ncontainer.configureFrame { maker in\n    maker.center()\n}\n```\n\nIf you have already configured container, then this method will be more convenient for you:\n\n```swift\n[content1, label1, label2, label3].configure(container: container, relation: .horizontal(left: 20, right: 20)) {\n// do configuration\n}\n```\n\n## Cool things:\n\nSometimes you want to configure a few views with the same size, for examlple. There is a convinience method:\n\n```swift\n[view1, view2].configureFrames { maker in\n    maker.size(width: 200, height: 100)\n}\n```       \n\n## Stack\n\nFramezilla allows you configure views like stack behaviour. Important to point out correct views order.\n\n![](img/stack.png)\n\n```swift\n[view3, view2, view1].stack(axis: .horizontal, spacing: 3)\n```\n\n## States\n\nIt's very convenient use many states for animations, because you can just configure all states in one place and when needed change frame for view - just apply needed state! Awesome, is'n it?\n\n![demo](img/animating.gif)\n\n```swift\noverride func viewDidLayoutSubviews() {\n  \n  super.viewDidLayoutSubviews()\n  \n  // state `DEFAULT_STATE`\n  view1.configureFrame { maker in\n      maker.centerX().and.centerY()\n      maker.width(50).and.height(50)\n  }\n  \n  view1.configureFrame(state: 1) { maker in\n      maker.centerX().and.centerY()\n      maker.width(100).and.height(100)\n  }\n}\n```\n\nset new state and animate it:\n\n```swift\n/* Next time when viewDidLayoutSubviews will be called, `view1` will configure frame for state 1. */\nview1.nx_state = 1 // Any hashable value\nview.setNeedsLayout()\nUIView.animate(withDuration: 1.0) {\n    self.view.layoutIfNeeded()\n}\n```\n\nAlso possible to apply many states in a row:\n\n```swift\nview1.configureFrame(states: [3, \"state\"]) { maker in\n    maker.size(width: 200, height: 100)\n}\n```\n\n# Author :muscle:\n\nNikita Ermolenko, nikita.ermolenko@rosberry.com\n\n# Thanks :+1:\nThanks [Artem Novichkov](https://github.com/artemnovichkov) for the name of the library!\n\nThanks [Evgeny Mikhaylov](https://github.com/medvedzzz) for 'state' feature!\n\nThanks [Anton Kovalev](https://github.com/Antowkos) for improving library!\n\n## Contribute :pray:\n\nI would love you to contribute to **Framezilla**, check the [CONTRIBUTING](https://github.com/Otbivnoe/Framezilla/blob/master/CONTRIBUTING.md) file for more info.\n\n# License :exclamation:\n\nFramezilla is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOtbivnoe%2FFramezilla","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOtbivnoe%2FFramezilla","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOtbivnoe%2FFramezilla/lists"}