Created
July 25, 2018 10:29
-
-
Save shaps80/b3985966798f3d3468883a8ff8e54504 to your computer and use it in GitHub Desktop.
Type-safe Swift 4+ wrapper around UITableView and UICollectionView cells, supplementary and decoration views.
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
import UIKit | |
/** | |
* Represents a general 'cell' type to provide conformance for UITableViewCell and UICollectionViewCell | |
*/ | |
public protocol ReusableCell: class { | |
static var reuseIdentifier: String { get } | |
} | |
extension ReusableCell { | |
public static var reuseIdentifier: String { | |
return String(describing: self) | |
} | |
} | |
public protocol ReuseableView: class { | |
static var kind: String { get } | |
} | |
extension ReuseableView { | |
public static var kind: String { | |
return String(describing: self) | |
} | |
} | |
extension UITableViewCell: ReusableCell { } | |
extension UICollectionReusableView: ReusableCell { } | |
extension UITableViewHeaderFooterView: ReusableCell { } | |
extension UICollectionReusableView: ReuseableView { } | |
/** | |
* Represents a general 'view' type to provide conformance for UITableView and UICollectionView. Includes register and dequeue calls so that we can handle both types, or even your own DataView types | |
*/ | |
public protocol ReusableCellHosting { | |
func register<C: ReusableCell>(cellClass: C.Type) | |
func dequeueCell<C: ReusableCell>(ofType cellClass: C.Type, for indexPath: IndexPath) -> C | |
func dequeueCell<C: ReusableCell>(with identifier: String, for indexPath: IndexPath) -> C | |
} | |
extension UITableView: ReusableCellHosting { | |
public func register<C: ReusableCell>(cellClass: C.Type) { | |
register(cellClass, forCellReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
public func registerNib<C: ReusableCell>(cellClass: C.Type, bundle: Bundle? = nil) { | |
let nib = UINib(nibName: String(describing: cellClass), bundle: bundle ?? Bundle(for: C.self)) | |
register(nib, forCellReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
public func registerHeaderFooterNib<C: ReusableCell>(cellClass: C.Type, bundle: Bundle? = nil) { | |
register(UINib(nibName: String(describing: cellClass), bundle: bundle ?? Bundle(for: C.self)), | |
forHeaderFooterViewReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
public func dequeueCell<C: ReusableCell>(ofType cellClass: C.Type, for indexPath: IndexPath) -> C { | |
// swiftlint:disable force_cast | |
return dequeueReusableCell(withIdentifier: cellClass.reuseIdentifier, for: indexPath) as! C | |
} | |
public func dequeueCell<C: ReusableCell>(with identifier: String, for indexPath: IndexPath) -> C { | |
// swiftlint:disable force_cast | |
return dequeueReusableCell(withIdentifier: identifier, for: indexPath) as! C | |
} | |
public func dequeueHeaderFooterView<C: ReusableCell>(ofType cellClass: C.Type) -> C { | |
// swiftlint:disable force_cast | |
return dequeueReusableHeaderFooterView(withIdentifier: cellClass.reuseIdentifier) as! C | |
} | |
} | |
extension UICollectionView { | |
public func dequeueCell<C: ReusableCell>(ofType cellClass: C.Type, for indexPath: IndexPath) -> C { | |
return dequeueReusableCell(withReuseIdentifier: cellClass.reuseIdentifier, for: indexPath) as! C | |
} | |
public func dequeueCell<C: ReusableCell>(with identifier: String, for indexPath: IndexPath) -> C { | |
return dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! C | |
} | |
public func register<C: ReusableCell>(cellClass: C.Type) { | |
self.register(cellClass, forCellWithReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
public func registerNib<C: ReusableCell>(for cellClass: C.Type, bundle: Bundle? = nil) { | |
self.register(UINib(nibName: cellClass.reuseIdentifier, bundle: bundle ?? Bundle(for: C.self)), | |
forCellWithReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
// Supplementary views | |
public func register<C: ReusableCell>(cellClass: C.Type, forKind kind: String) { | |
self.register(cellClass, forSupplementaryViewOfKind: kind, withReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
public func registerNib<C: ReusableCell>(for cellClass: C.Type, forSupplementaryViewOfKind kind: String, bundle: Bundle? = nil) { | |
self.register(UINib(nibName: cellClass.reuseIdentifier, bundle: bundle ?? Bundle(for: C.self)), | |
forSupplementaryViewOfKind: kind, withReuseIdentifier: cellClass.reuseIdentifier) | |
} | |
public func dequeueSupplementaryView<C: ReusableCell>(ofKind kind: String, ofType cellClass: C.Type, for indexPath: IndexPath) -> C { | |
return self.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: cellClass.reuseIdentifier, for: indexPath) as! C | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment