{"id":13462711,"url":"https://github.com/arnauddorgans/InfiniteLayout","last_synced_at":"2025-03-25T05:32:13.946Z","repository":{"id":45585882,"uuid":"115217826","full_name":"arnauddorgans/InfiniteLayout","owner":"arnauddorgans","description":"Horizontal and Vertical infinite scrolling feature for UICollectionView with Paging, NSProxy delegate, Reactive extension, SectionModel \u0026 AnimatableSectionModel support","archived":false,"fork":false,"pushed_at":"2021-07-10T17:22:43.000Z","size":16466,"stargazers_count":519,"open_issues_count":13,"forks_count":65,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-21T17:12:47.049Z","etag":null,"topics":[],"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/arnauddorgans.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-12-23T19:41:24.000Z","updated_at":"2025-02-11T10:26:47.000Z","dependencies_parsed_at":"2022-09-24T14:33:14.995Z","dependency_job_id":null,"html_url":"https://github.com/arnauddorgans/InfiniteLayout","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnauddorgans%2FInfiniteLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnauddorgans%2FInfiniteLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnauddorgans%2FInfiniteLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arnauddorgans%2FInfiniteLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arnauddorgans","download_url":"https://codeload.github.com/arnauddorgans/InfiniteLayout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245407571,"owners_count":20610227,"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":[],"created_at":"2024-07-31T13:00:19.326Z","updated_at":"2025-03-25T05:32:13.245Z","avatar_url":"https://github.com/arnauddorgans.png","language":"Swift","funding_links":[],"categories":["Swift","etc","collectionview collectionlayout"],"sub_categories":[],"readme":"# InfiniteLayout\n\n[![CI Status](http://img.shields.io/travis/arnauddorgans/InfiniteLayout.svg?style=flat)](https://travis-ci.org/arnauddorgans/InfiniteLayout)\n[![License](https://img.shields.io/cocoapods/l/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)\n[![Platform](https://img.shields.io/cocoapods/p/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)\n[![Version](https://img.shields.io/cocoapods/v/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)\n[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)\n\n\u003cimg src=\"https://github.com/arnauddorgans/InfiniteLayout/raw/master/horizontal.gif\" width=\"250\" height=\"540\"\u003e\u003cimg src=\"https://github.com/arnauddorgans/InfiniteLayout/raw/master/vertical.gif\" width=\"250\" height=\"540\"\u003e\u003cimg src=\"https://github.com/arnauddorgans/InfiniteLayout/raw/master/custom.gif\" width=\"250\" height=\"540\"\u003e\n\n\n## Example\n\nTo run the example project, clone the repo, and run `pod install` from the Example directory first.\n\n## Installation\n\n### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html)\n\nInfiniteLayout is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'InfiniteLayout'\n```\n\n\n### [Swift Package Manager](https://github.com/apple/swift-package-manager)\n\nCreate a `Package.swift` file.\n\n```swift\n// swift-tools-version:5.0\n\nimport PackageDescription\n\nlet package = Package(\n  name: \"InfiniteLayoutTestProject\",\n  dependencies: [\n    .package(url: \"https://github.com/arnauddorgans/InfiniteLayout.git\", from: \"0.4.2\")\n  ],\n  targets: [\n    .target(name: \"InfiniteLayoutTestProject\", dependencies: [\"InfiniteLayout\"])\n  ]\n)\n```\n\n## Usage\n\n```swift\n@IBOutlet weak var collectionView: InfiniteCollectionView!\n```\n\nInfiniteCollectionView doesn't need any other delegate or dataSource,\njust use UICollectionViewDataSource and UICollectionViewDelegate in the same way as you'll use it in any other UICollectionView.\n\nInfiniteLayout provides 3 classes for infinite scrolling:\n\n**InfiniteLayout**: an UICollectionViewFlowLayout\n\n**InfiniteCollectionView**: an UICollectionView with InfiniteLayout\n\n**InfiniteCollectionViewController**: an UICollectionViewController with InfiniteCollectionView\n\n### IndexPath\n\nInfiniteCollectionView may create fake indexPath,\n\nTo get the real indexPath call \n\n```swift\nfunc indexPath(from infiniteIndexPath: IndexPath) -\u003e IndexPath\n```\n\nTo get the real section call \n\n```swift\nfunc section(from infiniteSection: Int) -\u003e Int\n```\n\n### Paging\n\nInfiniteCollectionView provide a paging functionality, you can enable it by setting the **isItemPagingEnabled** flag to **true**\n\n```swift\nself.infiniteCollectionView.isItemPagingEnabled = true\n```\n\nWhen the **isItemPagingEnabled** flag is enabled you can adjust the deceleration rate by setting the **velocityMultiplier**, the more the value is high, the more the deceleration is long\n\n```swift\nself.infiniteCollectionView.velocityMultiplier = 1 // like scrollView with paging (default value)\nself.infiniteCollectionView.velocityMultiplier = 500 // like scrollView without paging\n```\n\nWhen the **isItemPagingEnabled** flag is enabled you can set a **preferredCenteredIndexPath**, this value is used to calculate the preferred visible cell to center each time the collectionView will change its contentSize\n\n```swift\nself.infiniteCollectionView.preferredCenteredIndexPath = [0, 0] // center the cell at [0, 0] if visible (default value)\nself.infiniteCollectionView.preferredCenteredIndexPath = nil // center the closest cell from center\n```\n\n### Delegate\n\n\u003cimg src=\"https://github.com/arnauddorgans/InfiniteLayout/raw/master/delegate.gif\" width=\"250\" height=\"540\"\u003e\n\nInfiniteCollectionView provide an **infiniteDelegate** protocol used to get the centered IndexPath, usefull if you want to use an InfiniteCollectionView like a Picker.\n\n```swift\nfunc infiniteCollectionView(_ infiniteCollectionView: InfiniteCollectionView, didChangeCenteredIndexPath from: IndexPath?, to: IndexPath?)\n```\n\n### Rx\n\nInfiniteCollectionView provide a subspec **InfiniteLayout/Rx**\n```ruby\npod 'InfiniteLayout/Rx'\n```\n\nTo use InfiniteCollectionView with RxSwift without conflicts between NSProxy\n\nUse **RxInfiniteCollectionView** instead of **InfiniteCollectionView**\n\n```swift\n@IBOutlet weak var collectionView: RxInfiniteCollectionView!\n```\n\nRxInfiniteCollectionView provides 2 dataSources for SectionModel:\n\n**RxInfiniteCollectionViewSectionedReloadDataSource** and **RxInfiniteCollectionViewSectionedAnimatedDataSource**\n\n#### Binding:\n\nWithout sections:\n```swift\n// automatic cell dequeue\nObservable.just(Array(0..\u003c2))\n    .bind(to: infiniteCollectionView.rx.items(cellIdentifier: \"cell\", cellType: Cell.self, infinite: true)) { row, element, cell in\n        cell.update(index: row) // update your cell\n    }.disposed(by: disposeBag)\n    \n// custom cell dequeue\nObservable.just(Array(0..\u003c2))\n    .bind(to: infiniteCollectionView.rx.items(infinite: true)) { collectionView, row, element in\n        let indexPath = IndexPath(row: row, section: 0)\n        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: \"cell\", for: indexPath) as! Cell // dequeue your cell\n        cell.update(index: row) // update your cell\n        return cell\n    }.disposed(by: disposeBag)\n```\n\nWith sections:\n```swift\nlet dataSource = RxInfiniteCollectionViewSectionedReloadDataSource\u003cSectionModel\u003cInt, Int\u003e\u003e(configureCell: { dataSource, collectionView, indexPath, element in\n    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: \"cell\", for: indexPath) as! Cell // dequeue your cell\n    cell.update(index: indexPath.row) // update your cell\n    return cell\n})\n\nObservable.just([\n                    SectionModel(model: 0, items: Array(0..\u003c2)),\n                    SectionModel(model: 1, items: Array(0..\u003c10))\n                ])\n    .bind(to: infiniteCollectionView.rx.items(dataSource: dataSource))\n    .disposed(by: disposeBag)\n```\n\nfor animations just use **RxInfiniteCollectionViewSectionedAnimatedDataSource** \u0026 **AnimatableSectionModel**\n\n#### Centered IndexPath:\n\nRxInfiniteCollectionView provide Reactive extension for **itemCentered** \u0026 **modelCentered**\n```swift\ninfiniteCollectionView.rx.itemCentered\n    .asDriver()\n    .drive(onNext: { [unowned self] indexPath in\n        self.selectedView.update(index: indexPath.row) // update interface with indexPath\n    }).disposed(by: disposeBag)\n\ninfiniteCollectionView.rx.modelCentered(Int.self)\n    .asDriver()\n    .drive(onNext: { [unowned self] element in\n        self.selectedView.update(index: element) // update interface with model\n    }).disposed(by: disposeBag)\n```\n\n## Author\n\nArnaud Dorgans, arnaud.dorgans@gmail.com\n\n## License\n\nInfiniteLayout 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%2Farnauddorgans%2FInfiniteLayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farnauddorgans%2FInfiniteLayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farnauddorgans%2FInfiniteLayout/lists"}