A simple but highly customizable `UICollectionViewLayout` for `UICollectionView`.



License platforms pod Carthage compatible Swift Package Manager compatible

Layout Designer




Custom implementations


This is a simple but powerful framework that lets you make complex layouts for your UICollectionView.
The implementation is quite simple. Just a custom UICollectionViewLayout that gives you the ability to apply transforms to the cells.
No UICollectionView inheritance or anything like that.
For more details, see How to use


This framework doesn't contain any external dependencies.


# Podfile

target 'YOUR_TARGET_NAME' do
    pod 'CollectionViewPagingLayout'

Replace YOUR_TARGET_NAME and then, in the Podfile directory, type:

$ pod install


Add this to Cartfile

github "CollectionViewPagingLayout"

and then, in the Cartfile directory, type:

$ carthage update

Swift Package Manager

using Xcode:

File > Swift Packages > Add Package Dependency


Just add all the files under Lib directory to your project

How to use

Using Layout Designer

There is a macOS app to make it even easier for you to build your custom layout.
It allows you to tweak many options and see the result in real-time.
It also generates the code for you. So, you can copy it to your project.

You can purchase the app from App Store and support this repository, or you can build it yourself from the source.
Yes, the macOS app is open-source too!.


  • First, make sure you imported the framework
import CollectionViewPagingLayout
  • Set up your UICollectionView as you always do (you need a custom class for cells)
  • Set the layout for your collection view: (in most cases you want a paging effect so enable that too)
let layout = CollectionViewPagingLayout()
collectionView.collectionViewLayout = layout
collectionView.isPagingEnabled = true // enabling paging effect

Note: Go to Prepared Transformable Protocols if you want to use prepared effects! to make a custom effect contiune.

  • Now, you just need to conform your cell class to TransformableView and start implementing your custom transforms. for instance:
class YourCell: UICollectionViewCell { /*...*/ }
extension YourCell: TransformableView {
  func transform(progress: CGFloat) {
    // apply changes on any view of your cell

As you see above, you get a progress value. Use that to apply any changes you want.

progress is a float value that represents the current position of your cell in the collection view.
When it's 0 that means the current position of the cell is exactly in the center of your collection view.
the value could be negative or positive and that represents the distance to the center of your collection view.
for instance 1 means the distance between the center of the cell and the center of your collection view is equal to your collection view width.

you can start with a simple transform like this:

extension YourCell: TransformableView {
    func transform(progress: CGFloat) {
        let transform = CGAffineTransform(translationX: bounds.width/2 * progress, y: 0)
        let alpha = 1 - abs(progress)

        contentView.subviews.forEach { $0.transform = transform }
        contentView.alpha = alpha
  • Don't forget to set numberOfVisibleItems, by default it's null and that means all of the cells will be loaded in the memory.
layout.numberOfVisibleItems = ...

Prepared Transformable Protocols

There are some prepared transformable protocols to make it easier to use this framework.
Using them is simple. You only need to conform your UICollectionViewCell to the protocol.
You can use the options property to tweak it as you want.
There are three types:

  • ScaleTransformView (orange previews)
  • SnapshotTransformView (green previews)
  • StackTransformView (blue previews)
    These protocols are highly customizable, you can make tons of different effects using them.
    Here is a simple example for ScaleTransformView which gives you a simple paging with scaling effect:
extension YourCell: ScaleTransformView {
    var scaleOptions = ScaleTransformViewOptions(
        minScale: 0.6,
        scaleRatio: 0.4,
        translationRatio: CGPoint(x: 0.66, y: 0.2),
        maxTranslationRatio: CGPoint(x: 2, y: 0),

There is an "options" property for each of these protocols where you can customize the effect, check the struct to find out what each parameter does.
A short comment on the top of each parameter explains what that does.
ScaleTransformView -> ScaleTransformViewOptions
SnapshotTransformView -> SnapshotTransformViewOptions
StackTransformView -> StackTransformViewOptions

See the examples in the samples app.
Check here to see used options for each: /PagingLayoutSamples/Modules/Shapes/ShapeCell/

Target view

You may wonder how does it find out the subview in your cell to apply transforms on.
If you check the transformable protocols, you find the target view for each. like ScaleTransformView.scalbleView.

The default value is the first subview of "contentView":

public extension ScaleTransformView where Self: UICollectionViewCell {
    /// Default `scalableView` for `UICollectionViewCell` is the first subview of
    /// `contentView` or the content view itself if there is no subview
    var scalableView: UIView {
        contentView.subviews.first ?? contentView

If that's not what you want, you can implement it.

Customize Prepared Transformables

Yes, you can customize them or even combine them.
To do that, implement TransformableView.transform function and call the transformable function manually, like this:

extension LayoutTypeCollectionViewCell: ScaleTransformView {
    func transform(progress: CGFloat) {
        applyScaleTransform(progress: progress)
        // customize views here, like this:
        titleLabel.alpha = 1 - abs(progress)
        subtitleLabel.alpha = titleLabel.alpha


As you see, applyScaleTransform applies the scale transforms and right after that we change the alpha for titleLabel and subtitleLabel.
To find the public function(s) of each protocol check the definition of that.

Other features

Control current page

You can control the current page by the following functions of CollectionViewPagingLayout:

  • func setCurrentPage(_ page: Int, animated: Bool = true)
  • func goToNextPage(animated: Bool = true)
  • func goToPreviousPage(animated: Bool = true)

These are safe wrappers around setting the ContentOffset of UICollectionview.
You can get the current page by a public variable CollectionViewPagingLayout.currentPage.
Listen to the changes via CollectionViewPagingLayout.delegate:

public protocol CollectionViewPagingLayoutDelegate: class {
    func onCurrentPageChanged(layout: CollectionViewPagingLayout, currentPage: Int)

Select Item At

As explained in the Limitations, you can't use collectionview's didSelectItemAt for more than one cell.
But, you can use this instead:

  • Implement TransformableView.selectableView and pass the view that you want to be selectable (by default it's the first subview of UICollectionViewCell.contentView)
  • Call layout.configureTapOnCollectionView() AFTER setting the layout for you collection view.
  • That's it. Now you get similar functionality by using CollectionViewPagingLayout.delegate instead of CollectionView.delegate
  • The method is func collectionViewPagingLayout(_ layout: CollectionViewPagingLayout, didSelectItemAt indexPath: IndexPath)


  • Specify the number of visible cells:

You need to specify the number of visible cells.
Since this layout gives you the flexibility to show the next and previous cells,
By default, it loads all of the cells in the collectionview's frame, which means iOS keeps all of them in the memory.
Based on your design, you can specify the number of cells that you need to show.

  • didSelectItemAt:

The way that this library works is by putting all of the cells in the collectionview's frame and applying transforms on the target-view
(StackTransformView.cardView, ScaleTransformView.scalableView and SnapshotTransformView.targetView).

So, you can use func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) but if you have multiple cells on screen only one of them is selectable! (because the others are below it).

You can implement func zPosition(progress: CGFloat) -> Int to specify which cell should be on the top.

This also means you can't handle any gesture for multiple cells.
But, there is a built-in solution to this, see Select Item At

  • It doesn't support RTL layouts


CollectionViewPagingLayout is available under the MIT license. See LICENSE file for more info.

  • Crash in modal view controller when swiping up on the controller.

    Crash in modal view controller when swiping up on the controller.

    Crashes when swiping up on the controller when having a collectionView with this layout presented modally. Only happens when the view is initially loaded and the first thing you do is swipe up.

    Will not crash when you swipe to a different card and swipe up. When you swipe up and it doesn't crash you get other cards reloading from the top left and expanding back into place every time you swipe.

    If you comment out viewDidLayoutSubviews code it will not crash but other issues are present.

    Error: [UICollectionViewData isIndexPathValid:validateItemCounts:]: message sent to deallocated instance

    opened by BubblyNetDev 13
  • Is there a way to have multiple cells appear on the collection view at once?

    Is there a way to have multiple cells appear on the collection view at once?

    Hi, thanks for the project, its super impressive. I saw some other issues people are having with the project and tried to use the suggestions you provided, but I am still facing some issues myself.

    It seems like, by design, the cells always take the entire collection view space. Is there any way that I can have multiple cells appear in the collection view?

    The issue i'm having is that the appearance is like this:

    Screen Shot 2021-03-29 at 2 05 26 PM

    The animations of the cells (scaling as I Scroll) work fine, but the other cells appear off screen.

    I think that if my collection view had a larger height, then it would appear normal, but I need to have a small collection view size. I tried manipulating the card size like in other examples you had, but it seems like just the card would get smaller and the cell would remain the same size as the collection view.

    opened by alanpridestar 10
  • Extensions must not contain stored properties

    Extensions must not contain stored properties

    Screen Shot 2020-10-11 at 09 40 24

    Hi Amir, How can I fix this error?

    opened by tranquocviet226 8
  • setCurrentPage(animated: false) with ScaleTransformView causes a stack of cells to form

    setCurrentPage(animated: false) with ScaleTransformView causes a stack of cells to form

    I have a ScaleTransformView, with a layout of 3 visible cells, that seems to work as expected.

    However, when calling setCurrentPage(animated = false), each of the 'visible cells' occupy the same frame as the 'primary' cell, causing a stack of three cells. As soon as you start dragging the primary cell, each of the 'visible cells' fall to their correct locations respectively.

    Setting animated: true results in expected behavior, however having it as true isn't ideal for my use case. I've already tried calling layoutIfNeeded(), but that seems to have no effect.

    opened by elrond140 7
  • iOS 8 warning in Xcode 12

    iOS 8 warning in Xcode 12

    In the latest version of Xcode 12, there is a warning associated with this package if installed via SwiftPM. This is because Xcode 12 drops support for iOS 8 and this package still supports it. Screenshot

    opened by CristianMoisei 5
  • Type of expression is ambiguous without more context (\.attributes)

    Type of expression is ambiguous without more context (\.attributes)

    in collectionviewpaginglayoutdelegate problem occurs Screen Shot 2020-07-13 at 1 24 28 AM

    opened by belalmedhat97 5
  • How to get top most card's index

    How to get top most card's index

    I want to get the topmost card's index which is being displayed. Pl guide me on how I can get it with your library. Thanks.

    opened by Travloper 4
  • support multi section collectionview

    support multi section collectionview

    Current Layout only for One Section List, add multi-sections list support

    opened by zzzworm 4
  • Next cell is not tappable.

    Next cell is not tappable.

    I've build an app which will allow user to like and share quotes by using your library but the problem is that after a swipe next cell action buttons are not capable. We've tried to fix this issue by using your delegate method but it is not working.

    Video attached - https://youtu.be/yVZlXM_TXbE

    opened by xLuciferSx 4
  • Build failed in Xcode 13 / iOS 15 Beta

    Build failed in Xcode 13 / iOS 15 Beta

    I'm using Xcode 13 (Beta 5) and iOS 15 Beta and have just started using this package. However, as soon as I include the package in my project I'm getting "Build Failed" and a couple of warnings.

    In total I get 10 swift compiler errors related to CollectionViewPagingLayout and two warnings, see attached print screen.

    Any ideas?


    Build Error
    opened by skegget 1
  • 1.0.2(Jun 13, 2021)

  • 1.0.1(May 18, 2021)

    • Fix a bug in animation completion closure, Use NSKeyValueObservation on contentOffset instead of CATransaction.setCompletionBlock
    • Fix an issue for selection not being updated if data gets reload
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Apr 25, 2021)

    New features:

    • Add SwiftUI support
    • ZPosition can be handled via CALayer or layout attribute or both, see CollectionViewPagingLayout.zPositionHandler
    • ViewAnimator: You can set the animation duration or implement your custom animator.
    • You can use the predefined layout options using an enum. for instance, ScaleTransformViewOptions.Layout.coverFlow
    • SnapshotTransformView.canReuse(snapshot:) You can define when the existing snapshots invalidate.


    • By default, zIndex will apply to the attribute and the CALayer, you can change it using CollectionViewPagingLayout.zPositionHandler
    • configureTapOnCollectionView and didSelectItemAt methods removed. You can use the built-in collectionview delegate instead!
    • Fix a problem: a page blinks before the transform effects apply on it, to fix it the attributes have alpha=0 by default before the cell is loaded. You can change it by setting "transparentAttributeWhenCellNotLoaded" to false
    • An bounds observer added for the collection view so, you don't need to call "invalidateLayout" on "viewDidLayoutSubviews"
    • If you are on page 1 and call setCurrentPage(4). the delegate method only gets called for page 4. previously, it was 2,3 and 4
    • ScaleTransformView.blurHost renamed to ScaleTransformView.scaleBlurHost
    • StackTransformView.blurHost renamed to StackTransformView.stackBlurHost
    • SnapshotTransformView.identifier renamed to SnapshotTransformView.snapshotIdentifier
    • Change default implementation of snapshotIdentifier to consider contentOffset of a possible scrollview inside a page
    Source code(tar.gz)
    Source code(zip)
  • 0.4.1(Mar 10, 2021)

  • 0.3.0(Jul 5, 2020)

    • Breaking change: use minTranslateRatios and maxTranslateRatios instead of minTranslates and maxTranslates for ScaleTransformView, it helps us to use the library on different screen sizes without changing the options, translateRatio is also works differently:
    translateX = progress * translates.x * targetView.width
    translateY = progress * translates.y * targetView.height
    translateZ = progress * translates.z * targetView.width
    // same for min and max
    • Layout designer code generator completed
    • Fix setCurrentPage related issues
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jul 4, 2020)

    • Introduce new iPad/Mac(Catalyst) app for designing layouts
    • New delegate function func collectionViewPagingLayout(_ layout: CollectionViewPagingLayout, didSelectItemAt indexPath: IndexPath) for using this func configureTapOnCollectionView(goToSelectedPage: Bool = false) needs to be called after assigning layout to the collection view - will be added to the ReadMe
    • Fix not change current page on animated page change
    • Fix zero sections
    Source code(tar.gz)
    Source code(zip)
  • 0.1.6(Jun 27, 2020)

  • 0.1.5(May 18, 2020)

  • 0.1.4(May 4, 2020)

  • 0.1.3(Apr 21, 2020)

  • 0.1.2(Apr 11, 2020)

  • 0.1.0(Apr 4, 2020)

    • Introducing Premade Transformable as a way to use the library faster
    • Introducing three Premade Transformables (Scale, Stack, Snapshot) with samples
    • Change the samples project to use the library as a Development Pod dependency
    • Introducing the new main page
    • Fix some issues and improve CollectionViewPagingLayout
    Source code(tar.gz)
    Source code(zip)
  • 0.0.6(Mar 10, 2020)

    • Fix issues with out of bounds layout attributes https://github.com/amirdew/CollectionViewPagingLayout/issues/5
    • Rename method name goToPrevPage -> goToPreviousPage
    Source code(tar.gz)
    Source code(zip)
Amir Khorsandi
Amir Khorsandi
Managing windows size and position in OSX

ShiftIt Managing window size and position in OSX Looking for a new maintainer #296. This project is looking for a new maintainer. Until that transitio

Filip Krikava 5.3k Sep 24, 2021
KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.

KeePassXC KeePassXC is a modern, secure, and open-source password manager that stores and manages your most sensitive information. You can run KeePass

KeePassXC 11.1k Sep 23, 2021
Find files with SQL-like queries

fselect Find files with SQL-like queries Why use fselect? While it doesn't tend to fully replace traditional find and ls, fselect has these nice featu

null 3k Sep 15, 2021
Adds numbered shortcuts to the output git status, and much more

SCM Breeze Streamline your SCM workflow. SCM Breeze is a set of shell scripts (for bash and zsh) that enhance your interaction with git. It integrates

SCM Breeze 2.5k Sep 23, 2021
:key: Cross-Platform Passwords Secrets Vault

Buttercup Desktop Buttercup for Desktop - Mac, Linux and Windows ² ⚠️ Buttercup v2 is in pre-release - It will reach its stable release channel soon A

Buttercup 3.6k Sep 10, 2021
AndroidUtilCode 🔥 is a powerful & easy to use library for Android

AndroidUtilCode ?? is a powerful & easy to use library for Android. This library encapsulates the functions that commonly used in Android development which have complete demo and unit test. By using it's encapsulated APIs, you can greatly improve the development efficiency. The program mainly consists of two modules which is utilcode, which is commonly used in development, and subutil which is rarely used in development, but the utils can be beneficial to simplify the main module. ??

Blankj 29.8k Sep 19, 2021
A crash log symbolicating Mac app | 一个图形化的崩溃日志符号化工具

SYM An app for crash symbolicating. Download the latest version from here. Features Apple/Umeng/Fabric crash report supporting. Automatic finding of d

上山打老虎 396 Sep 17, 2021
A floating browser window for OS X

Helium Helium is a floating browser window that allows you to watch media, browse the web and do much more while you stay productive. Your content wil

Jaden Geller 3.6k Sep 21, 2021
EnvPane - An OS X preference pane for environment variables

EnvPane - A macOS preference pane for environment variables EnvPane is a preference pane for Mac OS X (10.8 or newer) that lets you set environment va

Hannes Schmidt 549 Sep 19, 2021
Keep your application settings in sync (OS X/Linux)

Mackup Keep your application settings in sync. Table of content Quickstart Usage What does it do Bullsh*t, what does it really do to my files Supporte

Laurent Raufaste 11.4k Sep 23, 2021
Mounts archives like disk images (macOS)

Archive Mounter Archive Mounter is a macOS application allowing to mount archive files as disk images. It currently supports ZIP and RAR archives. War

Ilya Voronin 81 Aug 13, 2021
Simple screen and microphone audio recorder for Mac

Kyapchar Simple screen and microphone audio recorder for Mac Sneak Peek Following GIF image is a preview of this simple recorder which stays in toolba

Vishal Telangre 49 Sep 14, 2021
Simple macOS GateKeeper script.

macOS GateKeeper Helper Simple macOS GateKeeper script. ?? Table of Contents About Usage Tips ?? About This is a simple useful tool for users which al

Bahadır A. Güder 136 Sep 15, 2021
Simple network activity monitor for macOS

Loading See when Mac apps are using your network Similar to the network activity indicator on iOS, Loading shows a spinning progress wheel in your men

Mike McFadden 564 Sep 14, 2021
A simple, clean calendar and clock app for macOS.

CornerCal - a better clock app for macOS Download latest version: CornerCal.dmg.zip (supports macOS Sierra 10.12 and higher) A simple, clean calendar

Emil Kreutzman 222 Sep 13, 2021
Menu Bar RSS reader for macOS

baRSS – Menu Bar RSS Reader What is it? A RSS & Atom feed reader that lives in the system status bar. Very much inspired by RSS Menu; go ahead and che

Helena Schobs 34 Sep 16, 2021
Put the output from any script or program into your macOS Menu Bar (the BitBar reboot)

Welcome to xbar xbar (the BitBar reboot) lets you put the output from any script/program in your macOS menu bar. Complete rewrite from the ground up -

Mat Ryer 15.4k Sep 23, 2021
A simple app made to fix the sound issues that sometimes happen while using an external HDMI monitor on macOS (not tested after Mojave).

?? Mac Sound Re-Enabler ??‍♂️ Simple stupid app used to fix the sound issues (read below) while using an external HDMI monitor on macOS for video only

Nikola 18 Sep 9, 2021

Übersicht Keep an eye on what's happening on your machine and in the world. For general info check out the Übersicht website. Writing Widgets In essen

Felix 3.4k Sep 15, 2021