Skip to content

Instantly share code, notes, and snippets.

@ksmandersen
Created August 4, 2014 09:46
Show Gist options
  • Save ksmandersen/915de72261294433680b to your computer and use it in GitHub Desktop.
Save ksmandersen/915de72261294433680b to your computer and use it in GitHub Desktop.
//
// TableViewDataSource.swift
// QuickReply
//
// Created by Kristian Andersen on 31/07/14.
// Copyright (c) 2014 Robocat. All rights reserved.
//
import UIKit
private protocol KSCollectionViewDataSource {
func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int
func numberOfSectionsInCollectionView(collectionView: UICollectionView!) -> Int
func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
}
private protocol KSTableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView!) -> Int
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
}
private class BaseDataSource<CellType: UIView, ItemType>: KSCollectionViewDataSource, KSTableViewDataSource {
private var cellReuseIdentifier: String
private var configureClosure: (CellType, ItemType) -> Void
private var proxy: DataSourceProxy!
private unowned var view: UIView
init(view: UIView, cellReuseIdentifier: String, configureClosure: (CellType, ItemType) -> Void) {
self.cellReuseIdentifier = cellReuseIdentifier
self.configureClosure = configureClosure
self.view = view
configureDataSource()
}
private func configureDataSource() {
assert(view as? UITableView || view as? UICollectionView, "Passed view must be of type UITableView or UICollectionView")
self.proxy = DataSourceProxy(self)
if let tableView = view as? UITableView {
tableView.dataSource = proxy
}
if let collectionView = view as? UICollectionView {
collectionView.dataSource = proxy
}
}
func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int { return 0 }
func numberOfSectionsInCollectionView(collectionView: UICollectionView!) -> Int { return 0}
func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! { return nil }
func numberOfSectionsInTableView(tableView: UITableView!) -> Int { return 0 }
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { return 0 }
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { return nil }
private class DataSourceProxy: NSObject, UITableViewDataSource, UICollectionViewDataSource {
private unowned var dataSource: BaseDataSource<UIView, Any>
init(_ dataSource: AnyObject) {
self.dataSource = dataSource as BaseDataSource<UIView, Any>
}
// MARK: UITableViewDataSource
func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return dataSource.numberOfSectionsInTableView(tableView)
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return dataSource.tableView(tableView, numberOfRowsInSection: section)
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
return dataSource.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
// MARK: - UICollectionViewDataSource
func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int {
return dataSource.collectionView(collectionView, numberOfItemsInSection: section)
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView!) -> Int {
return dataSource.numberOfSectionsInCollectionView(collectionView)
}
func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! {
return dataSource.collectionView(collectionView, cellForItemAtIndexPath: indexPath)
}
}
}
public class ArrayDataSource<CellType: UIView, ItemType> : BaseDataSource<CellType, ItemType> {
private var items: [ItemType]
public init(items: [ItemType], view: UIView, cellReuseIdentifier: String, configureClosure: (CellType, ItemType) -> Void) {
self.items = items
super.init(view: view, cellReuseIdentifier: cellReuseIdentifier, configureClosure: configureClosure)
}
public func itemAtIndexPath(indexPath: NSIndexPath) -> ItemType {
return self.items[indexPath.row] as ItemType
}
public func configureCell(cell: CellType, atIndexPath indexPath:NSIndexPath) {
let item = itemAtIndexPath(indexPath)
self.configureClosure(cell, item)
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
if items.count <= 0 {
return 0
}
return 1
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier(self.cellReuseIdentifier, forIndexPath: indexPath) as CellType
configureCell(cell, atIndexPath: indexPath)
return cell as UITableViewCell
}
// MARK: - UICollectionViewDataSource
override func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int {
return items.count
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView!) -> Int {
if items.count <= 0 {
return 0
}
return 1
}
override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellReuseIdentifier, forIndexPath: indexPath) as CellType
configureCell(cell, atIndexPath: indexPath)
return cell as UICollectionViewCell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment