Skip to content

Instantly share code, notes, and snippets.

@werediver
Created January 23, 2016 11:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save werediver/8a26c87d85ff821ae78c to your computer and use it in GitHub Desktop.
Save werediver/8a26c87d85ff821ae78c to your computer and use it in GitHub Desktop.
Pretty universal UITableView / UICollectionView data source implementation in Swift.
import UIKit
class BaseSimpleDataSource<Cell: ReusableView, Collection: CollectionType
where Collection.Index == Int,
Collection.Generator.Element: CollectionType,
Collection.Generator.Element.Index == Int,
Collection.Generator.Element.Generator.Element == Cell.Model>: NSObject {
typealias Item = Cell.Model
var items: Collection? // [[section0item0, section0item1, ...], [section1item0, section1item1, ...], ...]
func itemByIndexPath(indexPath: NSIndexPath) -> Item {
return items![indexPath.section][indexPath.row]
}
var tuneCell: ((Cell, NSIndexPath) -> ())?
}
class SimpleTableViewDataSource<Cell: ReusableView, Collection: CollectionType
where Cell: UITableViewCell,
Collection.Index == Int,
Collection.Generator.Element: CollectionType,
Collection.Generator.Element.Index == Int,
Collection.Generator.Element.Generator.Element == Cell.Model>: BaseSimpleDataSource<Cell, Collection>, UITableViewDataSource {
// MARK: UITableViewDataSource
final func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return items?.count ?? 0
}
final func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items![section].count
}
final func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: Cell! = tableView.dequeueReusableCellWithIdentifier(Cell.reuseId, forIndexPath: indexPath) as! Cell
cell.loadModel(itemByIndexPath(indexPath))
tuneCell?(cell, indexPath)
return cell
}
}
class SimpleCollectionViewDataSource<Cell: ReusableView, Collection: CollectionType
where Cell: UICollectionViewCell,
Collection.Index == Int,
Collection.Generator.Element: CollectionType,
Collection.Generator.Element.Index == Int,
Collection.Generator.Element.Generator.Element == Cell.Model>: BaseSimpleDataSource<Cell, Collection>, UICollectionViewDataSource {
// MARK: UICollectionViewDataSource
final func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return items?.count ?? 0
}
final func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items![section].count
}
final func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: Cell! = collectionView.dequeueReusableCellWithReuseIdentifier(Cell.reuseId, forIndexPath: indexPath) as! Cell
cell.loadModel(itemByIndexPath(indexPath))
tuneCell?(cell, indexPath)
return cell
}
}
import Foundation
protocol View {
typealias Model
func loadModel(m: Model)
}
/// Use with `UITableViewCell` and `UICollectionView` subclasses.
protocol ReusableView: View {
static var reuseId: String { get }
}
extension ReusableView {
static var reuseId: String {
get {
return typeName(self)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment