CocoaPods trunk is moving to be read-only. Read more on the blog, there are 4 months to go.

LoopScroll 1.0.1

LoopScroll 1.0.1

Maintained by iLiuChang.



  • By
  • liuchang

LoopScroll

Swift Platform Version License SPM CocoaPods

Overview

An infinitely looping scroll control for iOS, built on UICollectionView. Provides two components:

  • LoopCollectionView — flexible infinite scrolling with custom item sizing and spacing
  • LoopPagingView — page-based infinite scrolling with configurable auto-scroll

Features

  • Infinite Scrolling — seamlessly loops through items in both directions using boundary-element padding
  • Custom Item Size & Spacing — configure itemSize and itemSpacing for non-full-width items, or leave default for full-page paging
  • Horizontal & Vertical — switch scroll direction with a single property
  • Auto Scroll — configurable timer-based automatic paging (LoopPagingView)
  • DataSource & Delegate — familiar UICollectionView-style protocols
  • Objective-C Compatible — all public APIs are @objc exposed

Requirements

  • iOS 11.0+
  • Swift 5.0+

Installation

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/iLiuChang/LoopScroll.git", from: "1.0.0")
]

CocoaPods

pod 'LoopScroll'

Usage

LoopCollectionView — Infinite Scrolling

import LoopScroll

let loopView = LoopCollectionView()
loopView.scrollDirection = .horizontal        // or .vertical
loopView.itemSize = 200                       // custom item width/height, 0 for full-page
loopView.itemSpacing = 10                     // spacing between items
loopView.dataSource = self
loopView.delegate = self
loopView.register(MyCell.self, forCellWithReuseIdentifier: "Cell")

LoopPagingView — Page-Based with Auto Scroll

import LoopScroll

let pagingView = LoopPagingView()
pagingView.scrollDirection = .horizontal
pagingView.autoScrollTimeInterval = 3.0       // 0 to disable auto-scroll
pagingView.disableLoopForSingleItem = true    // disable looping when only 1 item
pagingView.dataSource = self
pagingView.delegate = self
pagingView.register(MyCell.self, forCellWithReuseIdentifier: "Cell")

DataSource

extension ViewController: LoopCollectionViewDataSource {

    func numberOfItems(in loopCollectionView: LoopCollectionView) -> Int {
        return items.count
    }

    func loopCollectionView(_ loopCollectionView: LoopCollectionView, cellForItemAt index: Int) -> UICollectionViewCell {
        let cell = loopCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: index)
        // configure cell
        return cell
    }
}

Delegate

extension ViewController: LoopCollectionViewDelegate {

    func loopCollectionView(_ loopCollectionView: LoopCollectionView, didSelectItemAt index: Int) {
        print("Selected item at index: \(index)")
    }

    func loopCollectionView(_ loopCollectionView: LoopCollectionView, willDisplay cell: UICollectionViewCell, forItemAt index: Int) {
        pageControl.currentPage = index
    }
}

API Reference

LoopCollectionView

Property / Method Description
scrollDirection .horizontal or .vertical
itemSize Custom item size along scroll axis. 0 uses full bounds (page mode).
itemSpacing Spacing between adjacent items.
panGestureRecognizer The underlying UIPanGestureRecognizer.
reloadData() Reloads all items.
scrollToItem(at:animated:) Scrolls to a specific item.
register(_:forCellWithReuseIdentifier:) Registers a cell class or nib.

LoopPagingView (extends LoopCollectionView)

Property / Method Description
autoScrollTimeInterval Auto-scroll interval in seconds. 0 disables auto-scroll.
disableLoopForSingleItem When true, a single item won't loop and scrolling is disabled.
startTimer() Manually starts the auto-scroll timer.
cancelTimer() Manually stops the auto-scroll timer.

Note: itemSize and itemSpacing are locked to 0 in LoopPagingView — it always uses full-page sizing.

Delegate Methods

Method Description
shouldSelectItemAt Whether the item should be selected on tap.
didSelectItemAt Called when the user taps an item.
willDisplay:forItemAt Called before a cell becomes visible.
didEndDisplaying:forItemAt Called after a cell scrolls off screen.
willBeginDragging Called when the user starts dragging.
willEndDragging Called when the user stops dragging.
didScroll Called on every scroll event.
didEndScrollAnimation Called when a programmatic scroll animation finishes.
didEndDecelerating Called when scroll deceleration completes.
didEndDragging:willDecelerate Called when dragging ends with deceleration info.

Architecture

LoopCollectionView is a UIView subclass that internally manages a UICollectionView with UICollectionViewFlowLayout. It pads items with boundary elements at both ends and swaps contentOffset when the user scrolls past the boundaries, creating a seamless infinite loop. When itemSize is 0, it uses full bounds sizing with paging enabled for page-aligned snapping.

LoopPagingView extends LoopCollectionView, locking item size to full-page and adding a Timer-based auto-scroll mechanism that pauses during user interaction and resumes on release.

License

MIT License. See LICENSE for details.