A custom paging behavior that peeks the previous and next items in a collection view
MSPeekCollectionViewDelegateImplementation
Current design trends require complex designs which allow horizontal scrolling inside vertical scrolling. So to show the users that they can scroll vertically, a peeking item should be shown on the side. This library does exactly that. I wrote this library because there's no pod that does this simple feature. Also, other libraries require me to inherit from a UICollectionViewController, which doesn't give alot of freedom if I'm inheriting from other View Controllers.
Example
To run the example project, clone the repo, and run pod install
from the Example directory first.
Requirements
- XCode 9.3
- Swift 3.2
This pod will probably work on older versions of XCode but I haven't tested it.
Installation
MSPeekCollectionViewDelegateImplementation is available through CocoaPods. To install
it, simply add the following line to your Podfile:
pod 'MSPeekCollectionViewDelegateImplementation'
Usage
Storyboard
-
Drag-Drop a
UICollectionView
-
Set the reuse identifier for the collection view's cell to
Cell
-
Create a reference for the collection view
@IBOutlet weak var collectionView: UICollectionView!
-
Bind collection view to outlet
-
Import library
import MSPeekCollectionViewDelegateImplementation
- Create a variable of type
MSPeekCollectionViewDelegateImplementation
var delegate: MSPeekCollectionViewDelegateImplementation!
- In
viewDidLoad()
, Configure thecollectionView
for peek behavior:
collectionView.configureForPeekingDelegate()
- In
viewDidLoad()
, initialize the delegate using the basic initializer:
delegate = MSPeekCollectionViewDelegateImplementation()
Or you can use whatever arguments from the ones below (Can be combined together as needed):
delegate = MSPeekCollectionViewDelegateImplementation(cellSpacing: 10)
delegate = MSPeekCollectionViewDelegateImplementation(cellPeekWidth: 20)
//scrollThreshold is the minimum amount of scroll distance required to move to the adjacent item.
delegate = MSPeekCollectionViewDelegateImplementation(scrollThreshold: 150)
//maximumItemsToScroll is the maximum number of items that can be scrolled if the scroll distance is large
delegate = MSPeekCollectionViewDelegateImplementation(maximumItemsToScroll: 3)
//numberOfItemsToShow is the number of items that will be shown at the same time.
delegate = MSPeekCollectionViewDelegateImplementation(numberOfItemsToShow: 3)
- In
viewDidLoad()
, set the collection view's delegate:
collectionView.delegate = delegate
- Create the data source implementation as an extension for the
ViewController
extension ViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
//TODO: Configure cell
return cell
}
}
- In
viewDidLoad()
, Set the collection view's data source toself
collectionView.dataSource = self
Working Example
import UIKit
import MSPeekCollectionViewDelegateImplementation
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
let delegate = MSPeekCollectionViewDelegateImplementation()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.configureForPeekingDelegate()
collectionView.delegate = delegate
collectionView.dataSource = self
}
}
extension ViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
cell.contentView.backgroundColor = UIColor.red
return cell
}
}
Features
Getting the offset of a specific index
The implementation introduces a function (scrollView(_:,contentOffsetForItemAtIndex:) -> CGFloat
) to get the content offset of an item at a specific index. This can be helpful if you want to scroll the collection view programmatically to a specific index (Maybe create a carousel with a timer). You can do that by using the following code:
let secondItemContentOffset = delegate.scrollView(collectionView, contentOffsetForItemAtIndex: 1)
collectionView.setContentOffset(CGPoint(x: secondItemContentOffset, y: 0), animated: false)
Customization
Vertical Scroll Direction
The implementation supports collection views with vertical directions and will automatically position cells correctly, you can set the scrolling and peeking to be vertical using:
delegate = MSPeekCollectionViewDelegateImplementation(scrollDirection: .vertical)
collectionView.configureForPeekingDelegate(scrollDirection: .vertical)
Or alternatively:
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
delegate = MSPeekCollectionViewDelegateImplementation(scrollDirection: layout.scrollDirection)
collectionView.configureForPeekingDelegate(scrollDirection: layout.scrollDirection)
Subclassing
You can subclass the delegate implementation to integrate other features to it, or listen to certain events:
class SelectablePeekCollectionViewDelegateImplementation: MSPeekCollectionViewDelegateImplementation {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Item Selected")
}
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
super.scrollViewWillBeginDragging(scrollView)
// Add other code to support other features
}
}
Note: Make sure you call super on overriden functions (Unless you know what you're doing)