Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Nautiyalsachin/d726101bc7d49b597a5ad20bb311dc02 to your computer and use it in GitHub Desktop.
Save Nautiyalsachin/d726101bc7d49b597a5ad20bb311dc02 to your computer and use it in GitHub Desktop.
PickerCollectionViewFlowLayout use for custom paging in your existing code, used for multiple cell in your collection view with custom paging. //don't forget to disable the paging.
//
// PickerCollectionViewFlowLayout.swift
//
// Created by Sachin Nautiyal on 21/06/17.
// Copyright © 2017 Sachin Nautiyal. All rights reserved.
//
import UIKit
class PickerCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func awakeFromNib() {
super.awakeFromNib()
self.itemSize = CGSize(width: 50.0, height: 50.0) //if you want to define the cell size here.
self.scrollDirection = .horizontal // set your scrolling direction here. Right now its only for horizontal.
}
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
if let collectionView = collectionView,
let first = layoutAttributesForItem(at: IndexPath(row: 0, section: 0)),
let last = layoutAttributesForItem(at: IndexPath(row: collectionView.numberOfItems(inSection: 0) - 1, section: 0))
{
sectionInset = UIEdgeInsets(top: 0, left: collectionView.frame.width / 2 - first.bounds.size.width / 2, bottom: 0, right: collectionView.frame.width / 2 - last.bounds.size.width / 2)
}
let collectionViewSize = self.collectionView!.bounds.size
let proposedContentOffsetCenterX = proposedContentOffset.x + collectionViewSize.width * 0.5
var proposedRect = self.collectionView!.bounds
// comment this out if you don't want it to scroll so quickly
proposedRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionViewSize.width, height: collectionViewSize.height)
var candidateAttributes: UICollectionViewLayoutAttributes?
for attributes in self.layoutAttributesForElements(in: proposedRect)! {
// == Skip comparison with non-cell items (headers and footers) == //
if attributes.representedElementCategory != .cell {
continue
}
// Get collectionView current scroll position
let currentOffset = self.collectionView!.contentOffset
// Don't even bother with items on opposite direction
// You'll get at least one, or else the fallback got your back
if (attributes.center.x <= (currentOffset.x + collectionViewSize.width * 0.5) && velocity.x > 0) || (attributes.center.x >= (currentOffset.x + collectionViewSize.width * 0.5) && velocity.x < 0) {
continue
}
// First good item in the loop
if candidateAttributes == nil {
candidateAttributes = attributes
continue
}
// Save constants to improve readability
let lastCenterOffset = candidateAttributes!.center.x - proposedContentOffsetCenterX
let centerOffset = attributes.center.x - proposedContentOffsetCenterX
if fabsf( Float(centerOffset) ) < fabsf( Float(lastCenterOffset) ) {
candidateAttributes = attributes
}
}
if candidateAttributes != nil {
// Great, we have a candidate
return CGPoint(x: candidateAttributes!.center.x - collectionViewSize.width * 0.5, y: proposedContentOffset.y)
} else {
// Fallback
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment