Skip to content

Instantly share code, notes, and snippets.

@akpw
Last active June 28, 2017 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save akpw/4085c834aadef9c05d3fb7ec01d5997a to your computer and use it in GitHub Desktop.
Save akpw/4085c834aadef9c05d3fb7ec01d5997a to your computer and use it in GitHub Desktop.
// based on https://gist.github.com/gonzalezreal/92507b53d2b1e267d49a
import UIKit
protocol ReusableViewWithDefaultIdentifier {
static var defaultReuseIdentifier: String { get }
}
extension ReusableViewWithDefaultIdentifier where Self: UIView {
static var defaultReuseIdentifier: String {
let className = String(self)
return "\(className)DefaultReuseIdentifier"
}
}
protocol ReusableViewWithDefaultIdentifierAndKind: ReusableViewWithDefaultIdentifier {
static var defaultElementKind: String { get }
}
extension ReusableViewWithDefaultIdentifierAndKind where Self: UIView {
static var defaultElementKind: String {
let className = String(self)
return "\(className)DefaultElementKind"
}
}
protocol NibLoadableView {
static var nibName: String { get }
}
extension NibLoadableView where Self: UIView {
static var nibName: String {
return String(self)
}
}
extension UICollectionReusableView: ReusableViewWithDefaultIdentifierAndKind {}
extension UICollectionView {
// Register classes
func registerClass<T: UICollectionViewCell
where T: ReusableViewWithDefaultIdentifier>(_: T.Type) {
registerClass(T.self, forCellWithReuseIdentifier: T.defaultReuseIdentifier)
}
func registerClass<T: UICollectionReusableView
where T: ReusableViewWithDefaultIdentifier>(_: T.Type,
forSupplementaryViewOfKind elementKind: String) {
registerClass(T.self, forSupplementaryViewOfKind: elementKind,
withReuseIdentifier: T.defaultReuseIdentifier)
}
func registerClass<T: UICollectionReusableView
where T: ReusableViewWithDefaultIdentifierAndKind>(_: T.Type) {
registerClass(T.self, forSupplementaryViewOfKind: T.defaultElementKind,
withReuseIdentifier: T.defaultReuseIdentifier)
}
// Register nibs
func registerNib<T: UICollectionViewCell
where T: ReusableViewWithDefaultIdentifier, T: NibLoadableView>(_: T.Type) {
let nib = UINib(nibName: T.nibName, bundle: NSBundle(forClass: T.self))
registerNib(nib, forCellWithReuseIdentifier: T.defaultReuseIdentifier)
}
func registerNib<T: UICollectionReusableView
where T: ReusableViewWithDefaultIdentifier, T: NibLoadableView>(_: T.Type,
forSupplementaryViewOfKind elementKind: String) {
let nib = UINib(nibName: T.nibName, bundle: NSBundle(forClass: T.self))
registerNib(nib, forSupplementaryViewOfKind: elementKind,
withReuseIdentifier: T.defaultReuseIdentifier)
}
func registerNib<T: UICollectionReusableView
where T: ReusableViewWithDefaultIdentifierAndKind, T: NibLoadableView>(_: T.Type) {
let nib = UINib(nibName: T.nibName, bundle: NSBundle(forClass: T.self))
registerNib(nib, forSupplementaryViewOfKind: T.defaultElementKind,
withReuseIdentifier: T.defaultReuseIdentifier)
}
// Cells dequeueing
func dequeueReusableCell<T: UICollectionViewCell
where T: ReusableViewWithDefaultIdentifier>(forIndexPath indexPath: NSIndexPath) -> T {
guard let cell = dequeueReusableCellWithReuseIdentifier(T.defaultReuseIdentifier,
forIndexPath: indexPath) as? T else {
fatalError("Could not dequeue cell with identifier: \(T.defaultReuseIdentifier)")
}
return cell
}
// Dequeueing of reusable views
func dequeueReusableSupplementaryViewOfKind<T: UICollectionReusableView
where T: ReusableViewWithDefaultIdentifier> (elementKind: String,
forIndexPath indexPath: NSIndexPath) -> T {
guard let reusableView = dequeueReusableSupplementaryViewOfKind(elementKind,
withReuseIdentifier: T.defaultReuseIdentifier,
forIndexPath: indexPath) as? T else {
fatalError(String(format: "%@%@", "Could not dequeue reusable view of kind \(elementKind)",
"with identifier: \(T.defaultReuseIdentifier)"))
}
return reusableView
}
func dequeueReusableSupplementaryViewOfKind<T: UICollectionReusableView
where T: ReusableViewWithDefaultIdentifierAndKind> (forIndexPath indexPath: NSIndexPath) -> T {
guard let reusableView = dequeueReusableSupplementaryViewOfKind(T.defaultElementKind,
withReuseIdentifier: T.defaultReuseIdentifier,
forIndexPath: indexPath) as? T else {
fatalError(String(format: "%@%@", "Could not dequeue reusable view of kind \(T.defaultElementKind)",
"with identifier: \(T.defaultReuseIdentifier)"))
}
return reusableView
}
}
// ...
class CellWithID: UICollectionViewCell {
//...
}
let collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.registerClass(CellWithID.self)
// ...
//let cell: CellWithID = collectionView.dequeueReusableCell(forIndexPath: ...)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment