{"id":22689974,"url":"https://github.com/yahoojapan/uicollectionviewsplitlayout","last_synced_at":"2025-05-08T21:21:32.226Z","repository":{"id":56924826,"uuid":"155171556","full_name":"yahoojapan/UICollectionViewSplitLayout","owner":"yahoojapan","description":"UICollectionViewSplitLayout makes collection view more responsive.","archived":false,"fork":false,"pushed_at":"2019-10-06T12:48:43.000Z","size":89,"stargazers_count":245,"open_issues_count":0,"forks_count":13,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-14T06:39:09.544Z","etag":null,"topics":["ios","ipad","iphone","layout","swift","uicollectionview","uikit"],"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/yahoojapan.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":"2018-10-29T07:44:36.000Z","updated_at":"2024-12-24T07:37:45.000Z","dependencies_parsed_at":"2022-08-21T05:20:56.872Z","dependency_job_id":null,"html_url":"https://github.com/yahoojapan/UICollectionViewSplitLayout","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoojapan%2FUICollectionViewSplitLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoojapan%2FUICollectionViewSplitLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoojapan%2FUICollectionViewSplitLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yahoojapan%2FUICollectionViewSplitLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yahoojapan","download_url":"https://codeload.github.com/yahoojapan/UICollectionViewSplitLayout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253150082,"owners_count":21861831,"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","ipad","iphone","layout","swift","uicollectionview","uikit"],"created_at":"2024-12-10T00:24:37.004Z","updated_at":"2025-05-08T21:21:32.195Z","avatar_url":"https://github.com/yahoojapan.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![uicollectionviewsplitlayout_logo](https://user-images.githubusercontent.com/18320004/47694680-0420a280-dc42-11e8-98b4-55de463a735a.png)\n\n[![Platform](https://img.shields.io/cocoapods/p/UICollectionViewSplitLayout.svg?style=flat)](http://cocoapods.org/pods/UICollectionViewSplitLayout)\n![Swift 4.2](https://img.shields.io/badge/Swift-4.2-orange.svg)\n[![License](https://img.shields.io/cocoapods/l/UICollectionViewSplitLayout.svg?style=flat)](http://cocoapods.org/pods/UICollectionViewSplitLayout)\n[![Version](https://img.shields.io/cocoapods/v/UICollectionViewSplitLayout.svg?style=flat)](http://cocoapods.org/pods/UICollectionViewSplitLayout)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\nUICollectionViewSplitLayout makes collection view more responsive.\n\n![oct-30-2018 19-53-04](https://user-images.githubusercontent.com/18320004/47713409-8da19600-dc7d-11e8-896d-d868de48589f.gif)\n\n# What's this?\nUICollectionViewSplitLayout is a subclass of UICollectionViewLayout. It can divide sections into two columns.\n\nCollection view has \"Section\" which organizes item collection.\nUICollectionViewFlowLayout places them from top to bottom.\n\nOn the other hands, UICollectionViewSplitLayout divides sections into two columns.\nYou can dynamically update the width of them and which column each section is on.\n\nFor example, UICollectionViewSplitLayout can change the number of column according to device orientation. All you need is assigning value to ```leftSideRatio``` when changing screen size. This figure describes that a collection view has three sections (red, blue and green) and UICollectionViewSplitLayout aligns them side by side.\n\n![rendering_well](https://user-images.githubusercontent.com/18320004/47711313-4bc22100-dc78-11e8-9a05-16c1ac149f99.png)\n\nUICollectionViewSplitLayout looks like UIStackView. \nBut it has a more memory efficient architecture. \nSo you can align a lot of cells with it.\n\nIt may be hard to imagine how it works, please run [EmojiCollectionViewController](https://github.com/yahoojapan/UICollectionViewSplitLayout/blob/master/iOS%20Sample/iOS%20Sample/EmojiPhotosCollectionViewController/EmojiCollectionViewController.swift).\n\n# Requirement\n+ iOS 9.0+\n+ Swift 4.2\n\n# Installation\n\n### Carthage\n#### 1. create Cartfile\n\n```ruby:Cartfile\ngithub \"https://github.com/yahoojapan/UICollectionViewSplitLayout\"\n\n```\n\n#### 2. install\n```\n\u003e carthage update\n```\n\n### CocoaPods\n#### 1. create Podfile\n```ruby:Podfile\nplatform :ios, '8.0'\nuse_frameworks!\n\npod \"UICollectionViewSplitLayout\", :git =\u003e 'https://github.com/yahoojapan/UICollectionViewSplitLayout.git'\n```\n\n#### 2. install\n```\n\u003e pod install\n```\n\n# Getting Started\n\nIt’s good to start from replacing UICollectionViewFlowLayout with UICollectionViewSplitLayout.\n\n## 1. Create UICollectionViewController\n\nSet UICollectionViewController on Storyboard.\n\n\u003cimg width=\"300\" alt=\"2018-10-24 10 28 36\" src=\"https://user-images.githubusercontent.com/18320004/47400738-7e9c7e80-d779-11e8-9753-52e62ced2afc.png\"\u003e\n\nAdd implementation to construct a collection view.\n\n```swift\nimport UIKit\n\nprivate let reuseIdentifier = \"Cell\"\n\nclass BasicCollectionViewController: UICollectionViewController {\n    \n    var dataSource: [[UIColor]] = [\n        (0..\u003c20).map { _ in .red },\n        (0..\u003c20).map {  _ in .blue },\n        (0..\u003c20).map {  _ in .green }\n    ]\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)\n    }\n    // MARK: UICollectionViewDataSource\n\n    override func numberOfSections(in collectionView: UICollectionView) -\u003e Int {\n        return dataSource.count\n    }\n\n\n    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -\u003e Int {\n        return dataSource[section].count\n    }\n\n    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -\u003e UICollectionViewCell {\n        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)\n        cell.backgroundColor = dataSource[indexPath.section][indexPath.row]\n        return cell\n    }\n}\n```\n\nBuild the code.\n\n\u003cimg width=\"300\" alt=\"2018-10-24 10 27 42\" src=\"https://user-images.githubusercontent.com/18320004/47400781-b4d9fe00-d779-11e8-86e7-2d35ab45822c.png\"\u003e\n\nIt shows three sections whose items have different colors.\n\n## 2. Input \"UICollectionViewSplitLayout\" as Custom Layout Class\n\nSwitch \"Flow\" to \"Custom\" in Layout attribute and input \"UICollectionViewSplitLayout\" into Class and Module attributes.\n\n\u003cimg width=\"316\" alt=\"2018-10-30 11 07 59\" src=\"https://user-images.githubusercontent.com/18320004/47691120-1e538400-dc34-11e8-821b-3b9bafb2dbfc.png\"\u003e\n\n\n## 3. Assign parameters to UICollectionViewSplitLayout object\n\nConnect the layout class to source code. Assign the parameters on viewDidLoad()\n\n```swift\n    @IBOutlet weak var layout: UICollectionViewSplitLayout!\n \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        //...\n        //...\n        \n        // margins for each section\n        layout.minimumItemLineSpacing = 8\n        layout.minimumInterItemSpacing = 8\n        layout.sectionInset = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)\n        \n        // Column Setting\n        layout.leftSideRatio = 0.4\n        layout.splitSpacing = 8\n       \n        //...\n        //...\n    }\n```\n\n## 4. Implement the layout delegate for UICollectionViewSplitLayout\n\nImplement UICollectionViewDelegateTwoColumnLayout. The following methods is required.\n\n```swift\nextension BasicCollectionViewController: UICollectionViewDelegateSectionSplitLayout {\n    // Fix the size of each item as UICollectionViewDelegateFlowLayout does. calculateFixedWidthRaughly() is utility method UICollectionViewSplitLayout has.\n    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath, width: CGFloat, side: UICollectionViewSplitLayoutSide) -\u003e CGSize {\n        let width = layout.calculateFixedWidthRaughly(\n                               to: 3, \n                               of: side, \n                               minimumInterItemSpacing: layout.minimumInterItemSpacing, \n                               sectionInset: layout.sectionInset)\n        return CGSize(width: width, height: width)\n    }\n\n    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sideForSection section: Int) -\u003e UICollectionViewSplitLayoutSide {\n        // when a section number is odd, the items are placed into left side. \n        return section % 2 == 0 ? .left : .right\n    }\n}\n```\n\nIt arranges the sections side by side.\n\n\u003cimg width=\"300\" alt=\"2018-10-30 23 41 03\" src=\"https://user-images.githubusercontent.com/18320004/47726194-52af5a80-dc9d-11e8-82da-72e799837f6c.png\"\u003e\n\n\nSee [BasicCollectionViewController](https://github.com/yahoojapan/UICollectionViewSplitLayout/blob/master/iOS%20Sample/iOS%20Sample/BasicCollectionViewController/BasicCollectionViewController.swift) to run the above example.\n\n# Architecture\n\nIt is one of the UICollectionViewLayout. So you can change a layout without updating code in UICollectionViewDelegate and UICollectionViewDataSource. It is reasonable to apply a new layout. All you have to do is studying layout class and the delegate.\n\n# Usage\n\n## How to Split\n\nUICollectionViewSplitLayout calculates width of the left and right side with the following parameter.\n\n```swift\nleftSideRatio = 0.4\n```\n\nIt has a Float value which is the ration of left side to the entire width. \nIn addition, left and right sides have spacing between them.\n\n```swift\nsplitSpacing = 10\n```\n\nIf a collection view has 110pt width, the above setting requires 40pt width to the left side and 60pt width to the right side.\nWhen leftSideRatio has 0.0, splitSpacing is ignored as an exception.\n\nYou can choose which side each section is in. UICollectionViewDeleagteSectionSplitLayout provides a method to do that.\n\n```swift\nfunc collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sideForSection section: Int) -\u003e UICollectionViewSplitLayoutSide\n```\n\nUICollectionViewSplitLayout hooks the delegate every time a collection view calls invalidateLayout().\n\n## Margins\n\nUICollectionViewSplitLayout has these parameters to determine margins.\n\n```swift\n/// The minimum spacing to use between items in the same row.\nopen var minimumInterItemSpacing: CGFloat\n/// The minimum spacing to use between lines of items in the grid.\nopen var minimumItemLineSpacing: CGFloat\n/// The margins used to lay out content in a section\nopen var sectionInset: UIEdgeInsets\n```\n\nThey have the corresponding delegate methods by section (optional).\n\n```swift\n// section inset to each section\n@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int, side: UICollectionViewSplitLayoutSide) -\u003e UIEdgeInsets\n    \n// minimumInterItemSpacing to each section\n@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInterItemSpacingForSectionAtIndex section: Int, side: UICollectionViewSplitLayoutSide) -\u003e CGFloat\n\n// minimumItemLineSpacing to each section\n@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumItemLineSpacingForSectionAtIndex section: Int, side: UICollectionViewSplitLayoutSide) -\u003e CGFloat\n```\n\n## Pinning (iOS 11~)\n\nUICollectionViewSplitLayout pins seciton header like UICollectionViewFlowLayout. This feature is supported from iOS 11. ```sectionPinToVisibleBounds``` enables to work it.\n\n## Setting Attriutes\n\nUICollectionViewSplitLayout uses three kinds of attribute, item, supplementary view and decoration view.\n\n### Item \nYou need to implement cell sizing. UICollectionViewSplitLayout provides a delegate to implement it.\n\n```swift\nfunc collectionView(\n    _ collectionView: UICollectionView, \n    layout collectionViewLayout: UICollectionViewLayout, \n    sizeForItemAtIndexPath indexPath: IndexPath, \n    width: CGFloat, \n    side: UICollectionViewSplitLayoutSide) -\u003e CGSize\n```\n\nYou can divide the sizes evenly with a utility method.\n\n```swift\nopen func calculateFixedWidthRaughly(\n    to num: Int, \n    of side: UICollectionViewSplitLayoutSide, \n    minimumInterItemSpacing: CGFloat, \n    sectionInset: UIEdgeInsets) -\u003e CGFloat\n```\n\n### Supplementary view for header and footer\nYou can implement header and footer sizing. UICollectionViewSplitLayout provides delegate to implement it. \nIf the sizes are zero, header and footer are ignoured.\n\n```swift size\n// header\n@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int, width: CGFloat, side: UICollectionViewSplitLayoutSide) -\u003e CGSize\n\n// footer size\n@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int, width: CGFloat, side: UICollectionViewSplitLayoutSide) -\u003e CGSize\n```\n\n### decoration view for backgroundColor\n\nUICollectionSplitLayout has a special decoration view. It has the same size as the section. You can determine backgroundColor to each section with the following delegate.\n\n```swift\n@objc optional func collectionView(\n    _ collectionView: UICollectionView, \n    layout collectionViewLayout: UICollectionViewLayout,\n    itemsBackgroundColorFor section: Int, \n    side: UICollectionViewSplitLayoutSide) -\u003e UIColor?\n```\n\n## Line Height Normalization\nIf isNormalizingLineHeight is true, item height is adjusted to outline height of the line (defalut: false).\n\n```swift\nopen var isNormalizingLineHeight: Bool\n```\n\n# License\n\nThe MIT License (MIT)\n\nCopyright (c) 2018 Yahoo Japan Corporation\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyahoojapan%2Fuicollectionviewsplitlayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyahoojapan%2Fuicollectionviewsplitlayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyahoojapan%2Fuicollectionviewsplitlayout/lists"}