{"id":19517902,"url":"https://github.com/iwheelbuy/squaremosaiclayout","last_synced_at":"2025-04-03T02:10:59.762Z","repository":{"id":43932735,"uuid":"77621597","full_name":"iwheelbuy/SquareMosaicLayout","owner":"iwheelbuy","description":"An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations :large_orange_diamond:","archived":false,"fork":false,"pushed_at":"2019-03-21T14:38:22.000Z","size":1335,"stargazers_count":257,"open_issues_count":4,"forks_count":18,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-24T18:58:10.009Z","etag":null,"topics":["ios","swift","uicollectionview","uicollectionviewflowlayout","uicollectionviewlayout","uikit","uitableview"],"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/iwheelbuy.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","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":"2016-12-29T15:30:48.000Z","updated_at":"2024-04-02T17:40:23.000Z","dependencies_parsed_at":"2022-08-26T07:50:58.726Z","dependency_job_id":null,"html_url":"https://github.com/iwheelbuy/SquareMosaicLayout","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwheelbuy%2FSquareMosaicLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwheelbuy%2FSquareMosaicLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwheelbuy%2FSquareMosaicLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwheelbuy%2FSquareMosaicLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iwheelbuy","download_url":"https://codeload.github.com/iwheelbuy/SquareMosaicLayout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246922247,"owners_count":20855345,"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","swift","uicollectionview","uicollectionviewflowlayout","uicollectionviewlayout","uikit","uitableview"],"created_at":"2024-11-11T00:07:09.835Z","updated_at":"2025-04-03T02:10:59.731Z","avatar_url":"https://github.com/iwheelbuy.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SquareMosaicLayout\n\n[![Version](https://img.shields.io/cocoapods/v/SquareMosaicLayout.svg?style=flat)](https://cocoapods.org/pods/SquareMosaicLayout)\n[![License](https://img.shields.io/cocoapods/l/SquareMosaicLayout.svg?style=flat)](https://raw.githubusercontent.com/iwheelbuy/SquareMosaicLayout/master/LICENSE)\n![Platform](https://img.shields.io/cocoapods/p/SquareMosaicLayout.svg?style=flat)\n\nAn extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations.\n\n## Note\n\nThis layout is not of [waterfall](https://www.raywenderlich.com/107439/uicollectionview-custom-layout-tutorial-pinterest) type. It was designed for layouts where we can predict the size of rectangular box which contains the number of full cells. Check out how to copy [TRMosaicLayout](https://github.com/iwheelbuy/SquareMosaicLayout#example---copying-trmosaiclayout) or [FMMosaicLayout](https://github.com/iwheelbuy/SquareMosaicLayout#example---copying-fmmosaiclayout) using __SquareMosaicLayout__\n\n## Visual\n\n| Example | Layout | Pattern | Blocks |\n|:-:|:-:|:-:|:-:|\n| ![image1](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/ezgif.com-optimize.gif) | ![image2](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/rsz_1.png) | ![image3](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/rsz_12.png) | ![image4](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/rsz_3.png) |\n| Build and run an example project to see how it really works | Let's imagine that we want a UICollectionView with some mosaic layout that looks like this | The red part of frames repeats while scrolling. So we should do only the red __pattern__ and then repeat it | The __pattern__ is split it into smaller __blocks__ that can be reused for some other layout or __pattern__ |\n\n## Installation\n\nSquareMosaicLayout is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'SquareMosaicLayout', '4.1.2'\n```\n\n## Capabilities\n\n- [x] Layout can be vertical or horizontal.\n- [x] Each section can have its own __pattern__ of frames.\n- [x] Each section can have its own header frame (optional).\n- [x] Each section can have its own footer frame (optional).\n- [x] Each section can have its own background (optional).\n- [x] Space between sections can be changed (optional).\n- [x] Space between, before and after __blocks__ in __pattern__ can be changed (optional).\n- [x] Each section can have one repeated __block__.\n\n## Author\n\niwheelbuy, iwheelbuy@gmail.com\n\n## License\n\nSquareMosaicLayout is available under the MIT license. See the [LICENSE](https://raw.githubusercontent.com/iwheelbuy/SquareMosaicLayout/master/LICENSE) file for more info.\n\n## Example - copying [TRMosaicLayout](https://github.com/vinnyoodles/TRMosaicLayout)\n\n```swift\nfinal class TRMosaicLayoutCopy: SquareMosaicLayout, SquareMosaicDataSource {\n    \n    convenience init() {\n        self.init(direction: SquareMosaicDirection.vertical)\n        self.dataSource = self\n    }\n\n    func layoutPattern(for section: Int) -\u003e SquareMosaicPattern {\n        return TRMosaicLayoutCopyPattern()\n    }\n}\n\nclass TRMosaicLayoutCopyPattern: SquareMosaicPattern {\n    \n    func patternBlocks() -\u003e [SquareMosaicBlock] {\n        return [\n            TRMosaicLayoutCopyBlock1(),\n            TRMosaicLayoutCopyBlock2()\n        ]\n    }\n}\n\npublic class TRMosaicLayoutCopyBlock1: SquareMosaicBlock {\n    \n    public func blockFrames() -\u003e Int {\n        return 3\n    }\n    \n    public func blockFrames(origin: CGFloat, side: CGFloat) -\u003e [CGRect] {\n        let minWidth = side / 3.0\n        let maxWidth = side - minWidth\n        let minHeight = minWidth * 1.5\n        let maxHeight = minHeight + minHeight\n        var frames = [CGRect]()\n        frames.append(CGRect(x: 0, y: origin, width: maxWidth, height: maxHeight))\n        frames.append(CGRect(x: maxWidth, y: origin, width: minWidth, height: minHeight))\n        frames.append(CGRect(x: maxWidth, y: origin + minHeight, width: minWidth, height: minHeight))\n        return frames\n    }\n}\n\npublic class TRMosaicLayoutCopyBlock2: SquareMosaicBlock {\n    \n    public func blockFrames() -\u003e Int {\n        return 3\n    }\n    \n    public func blockFrames(origin: CGFloat, side: CGFloat) -\u003e [CGRect] {\n        let minWidth = side / 3.0\n        let maxWidth = side - minWidth\n        let minHeight = minWidth * 1.5\n        let maxHeight = minHeight + minHeight\n        var frames = [CGRect]()\n        frames.append(CGRect(x: 0, y: origin, width: minWidth, height: minHeight))\n        frames.append(CGRect(x: 0, y: origin + minHeight, width: minWidth, height: minHeight))\n        frames.append(CGRect(x: minWidth, y: origin, width: maxWidth, height: maxHeight))\n        return frames\n    }\n}\n```\n\n## Example - copying [FMMosaicLayout](https://github.com/fmitech/FMMosaicLayout)\n\n```swift\nfinal class FMMosaicLayoutCopy: SquareMosaicLayout, SquareMosaicDataSource {\n    \n    convenience init() {\n        self.init(direction: SquareMosaicDirection.vertical)\n        self.dataSource = self\n    }\n    \n    func layoutPattern(for section: Int) -\u003e SquareMosaicPattern {\n        return FMMosaicLayoutCopyPattern()\n    }\n}\n\nclass FMMosaicLayoutCopyPattern: SquareMosaicPattern {\n    \n    func patternBlocks() -\u003e [SquareMosaicBlock] {\n        return [\n            FMMosaicLayoutCopyBlock1(),\n            FMMosaicLayoutCopyBlock2(),\n            FMMosaicLayoutCopyBlock3(),\n            FMMosaicLayoutCopyBlock2(),\n            FMMosaicLayoutCopyBlock2()\n        ]\n    }\n}\n\npublic class FMMosaicLayoutCopyBlock1: SquareMosaicBlock {\n    \n    public func blockFrames() -\u003e Int {\n        return 5\n    }\n    \n    public func blockFrames(origin: CGFloat, side: CGFloat) -\u003e [CGRect] {\n        let min = side / 4.0\n        let max = side - min - min\n        var frames = [CGRect]()\n        frames.append(CGRect(x: 0, y: origin, width: max, height: max))\n        frames.append(CGRect(x: max, y: origin, width: min, height: min))\n        frames.append(CGRect(x: max, y: origin + min, width: min, height: min))\n        frames.append(CGRect(x: max + min, y: origin, width: min, height: min))\n        frames.append(CGRect(x: max + min, y: origin + min, width: min, height: min))\n        return frames\n    }\n}\n\npublic class FMMosaicLayoutCopyBlock2: SquareMosaicBlock {\n    \n    public func blockFrames() -\u003e Int {\n        return 4\n    }\n    \n    public func blockFrames(origin: CGFloat, side: CGFloat) -\u003e [CGRect] {\n        let min = side / 4.0\n        var frames = [CGRect]()\n        frames.append(CGRect(x: 0, y: origin, width: min, height: min))\n        frames.append(CGRect(x: min, y: origin, width: min, height: min))\n        frames.append(CGRect(x: min * 2, y: origin, width: min, height: min))\n        frames.append(CGRect(x: min * 3, y: origin, width: min, height: min))\n        return frames\n    }\n}\n\npublic class FMMosaicLayoutCopyBlock3: SquareMosaicBlock {\n    \n    public func blockFrames() -\u003e Int {\n        return 5\n    }\n    \n    public func blockFrames(origin: CGFloat, side: CGFloat) -\u003e [CGRect] {\n        let min = side / 4.0\n        let max = side - min - min\n        var frames = [CGRect]()\n        frames.append(CGRect(x: 0, y: origin, width: min, height: min))\n        frames.append(CGRect(x: 0, y: origin + min, width: min, height: min))\n        frames.append(CGRect(x: min, y: origin, width: min, height: min))\n        frames.append(CGRect(x: min, y: origin + min, width: min, height: min))\n        frames.append(CGRect(x: max, y: origin, width: max, height: max))\n        return frames\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiwheelbuy%2Fsquaremosaiclayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiwheelbuy%2Fsquaremosaiclayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiwheelbuy%2Fsquaremosaiclayout/lists"}