Usage
January 24, 2020 ยท View on GitHub
How to install and use this module.
Installation
CenteredCollectionView is available through Swift Package Manager, CocoaPods and Carthage.
To install it with Swift Package Manager, add the URL https://github.com/BenEmdon/CenteredCollectionView in Xcode Add Package Dependency assistant ; or add to your own Package.swift:
dependencies: [
.package(url: "https://github.com/BenEmdon/CenteredCollectionView", from: "2.2.2")
]
To install it with Cocoapods, add the following line to your Podfile:
pod "CenteredCollectionView"
To install it with Carthage, add the following line to your Cartfile:
github "BenEmdon/CenteredCollectionView"
Storyboard Usage
-
To start off lets add a
UICollectionViewto our controller, and lay it out however you want it.
-
Next lets set the
UICollectionView's custom layout to beCenteredCollectionViewFlowLayout.
-
Next we can optionally layout the prototype item. Note that this doesn't determine the item's size.

-
Let's create an example cell subclass that contains the views we want to present. Create a new file named "UserCollectionViewCell", with the following code:
import UIKit class UserCollectionViewCell: UICollectionViewCell { }Next, set the prototype item in the Storyboard to subclass from here:

Finally, add a label to the cell and create a corresponding outlet in the
UserCollectionViewCellsubclass.
Don't forget to add a cell identifier!

-
Create an
IBOutletfor the collection view.
-
Next lets dive in to the code use:
import CenteredCollectionView
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
// The width of each cell with respect to the screen.
// Can be a constant or a percentage.
let cellPercentWidth: CGFloat = 0.7
// A reference to the `CenteredCollectionViewFlowLayout`.
// Must be aquired from the IBOutlet collectionView.
var centeredCollectionViewFlowLayout: CenteredCollectionViewFlowLayout!
override func viewDidLoad() {
super.viewDidLoad()
// Get the reference to the `CenteredCollectionViewFlowLayout` (REQUIRED STEP)
centeredCollectionViewFlowLayout = collectionView.collectionViewLayout as! CenteredCollectionViewFlowLayout
// Modify the collectionView's decelerationRate (REQUIRED STEP)
collectionView.decelerationRate = UIScrollViewDecelerationRateFast
// Assign delegate and data source
collectionView.delegate = self
collectionView.dataSource = self
// Configure the required item size (REQUIRED STEP)
centeredCollectionViewFlowLayout.itemSize = CGSize(
width: view.bounds.width * cellPercentWidth,
height: view.bounds.height * cellPercentWidth * cellPercentWidth
)
// Configure the optional inter item spacing (OPTIONAL STEP)
centeredCollectionViewFlowLayout.minimumLineSpacing = 20
// Get rid of scrolling indicators
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
}
}
As with any UICollectionView, you'll also need to conform to the UICollectionViewDelegate and UICollectionViewDataSource protocols, as follows:
// Here's an example model we'll use.
struct User {
var name: String
}
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
// ... properties as before
// Instance of our example data model
var users = [User]()
override func viewDidLoad() {
// ...
// Flush the model with some example data
users.append(User("User1"))
users.append(User("User2"))
users.append(User("User3"))
}
// MARK: UICollectionViewDelegate
// Now, we'll conform to the delegates that we promised in the viewDidLoad earlier
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return users.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// Grab our cell from dequeueReusableCell, wtih the same identifier we set in our storyboard.
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? UserCollectionViewCell
// Error checking, if our cell is somehow not able to be cast
guard let userCell = cell else {
print("Unable to instantiate user cell at index \(indexPath.row)")
return cell
}
// Give the current cell the corresponding data it needs from our model
userCell.label.text = users[indexPath.row].name
return userCell
}
}
Programmatic Usage
class ViewController: UIViewController {
let centeredCollectionViewFlowLayout = CenteredCollectionViewFlowLayout()
let collectionView: UICollectionView
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
// Initialize the collectonView with the `CenteredCollectionViewFlowLayout` (REQUIRED STEP)
collectionView = UICollectionView(centeredCollectionViewFlowLayout: centeredCollectionViewFlowLayout)
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Assign delegate and data source
collectionView.delegate = self
collectionView.dataSource = self
// Layout subviews (not shown)
...
// Register collection cells (REQUIRED STEP)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: String(describing: UICollectionViewCell.self))
// Configure the required item size (REQUIRED STEP)
centeredCollectionViewFlowLayout.itemSize = CGSize(
width: view.bounds.width * cellPercentWidth,
height: view.bounds.height * cellPercentWidth * cellPercentWidth
)
// Configure the optional inter item spacing (OPTIONAL STEP)
centeredCollectionViewFlowLayout.minimumLineSpacing = 20
// Get rid of scrolling indicators
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
}
}
// Delegate and datasource extensions
...
Scroll to Edge Effect

Scrolling to an Edge on Touch ๐ก
Heres how you could trigger a scroll animation when a touch happens on an item that isn't the currentCenteredPage:
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// check if the currentCenteredPage is not the page that was touched
let currentCenteredPage = centeredCollectionViewFlowLayout.currentCenteredPage
if currentCenteredPage != indexPath.row {
// trigger a scrollToPage(index: animated:)
centeredCollectionViewFlowLayout.scrollToPage(index: indexPath.row, animated: true)
}
}
}