Forked from andymatuschak/CollectionViewDataSource.swift
Created
October 28, 2015 17:04
-
-
Save neilpa/b9491c8ffbb454ed2af2 to your computer and use it in GitHub Desktop.
Type-safe value-oriented collection view data source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CollectionViewDataSource.swift | |
// Khan Academy | |
// | |
// Created by Andy Matuschak on 10/14/14. | |
// Copyright (c) 2014 Khan Academy. All rights reserved. | |
// | |
import UIKit | |
/// A type which can produce and configure a cell for a given item. | |
public protocol CollectionViewCellFactoryType { | |
typealias Item | |
typealias Cell: UICollectionViewCell | |
func cellForItem(item: Item, inCollectionView collectionView: UICollectionView, atIndexPath indexPath: NSIndexPath) -> Cell | |
} | |
/// A concrete cell factory which makes use of UICollectionView's built-in cell reuse queue. | |
public struct RegisteredCollectionViewCellFactory<Cell: UICollectionViewCell, Item>: CollectionViewCellFactoryType { | |
private let reuseIdentifier: String | |
private let cellConfigurator: (Cell, Item) -> () | |
/// You must register Cell.Type with your collection view for `reuseIdentifier`. | |
public init(reuseIdentifier: String, cellConfigurator: (Cell, Item) -> ()) { | |
self.reuseIdentifier = reuseIdentifier | |
self.cellConfigurator = cellConfigurator | |
} | |
public func cellForItem(item: Item, inCollectionView collectionView: UICollectionView, atIndexPath indexPath: NSIndexPath) -> Cell { | |
// Will abort if you haven't already registered this reuse identifier for Cell.Type. | |
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! Cell | |
cellConfigurator(cell, item) | |
return cell | |
} | |
} | |
/// A type-safe collection view data source. Clients can specify its sections and their contents via any CollectionType. Configuration of the cells is delegated to an external factory type. | |
/// Use `bridgedDataSource` to get a UICollectionViewDataSource instance. | |
public class CollectionViewDataSource< | |
SectionCollection: CollectionType, | |
Factory: CollectionViewCellFactoryType, | |
Item | |
where | |
SectionCollection.Index == Int, | |
SectionCollection.Generator.Element: CollectionType, | |
SectionCollection.Generator.Element.Generator.Element == Item, | |
SectionCollection.Generator.Element.Index == Int, | |
Factory.Item == Item | |
>: NSObject, UICollectionViewDataSource { | |
/// Clients are responsible for inserting/removing items in the collection view itself. | |
public var sections: SectionCollection | |
private let cellFactory: Factory | |
public init(sections: SectionCollection, cellFactory: Factory) { | |
self.sections = sections | |
self.cellFactory = cellFactory | |
super.init() | |
} | |
final public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { | |
return sections.count | |
} | |
final public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
return sections[section].count | |
} | |
final public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { | |
return cellFactory.cellForItem(sections[indexPath.section][indexPath.row], inCollectionView: collectionView, atIndexPath: indexPath) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... | |
let cellFactory = RegisteredCollectionViewCellFactory(reuseIdentifier: "Topic") { (cell: TopicCatalogCell, topic: Topic) in | |
cell.topic = topic | |
} | |
dataSource = CollectionViewDataSource(sections: [topics], cellFactory: cellFactory) | |
topicCollectionView = UICollectionView(frame: CGRect(), collectionViewLayout: topicCollectionViewLayout) | |
topicCollectionView.dataSource = dataSource |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated for Swift 2