Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rtimpone/e7a625afd4372f59d2b94bc0ca4c163a to your computer and use it in GitHub Desktop.
Save rtimpone/e7a625afd4372f59d2b94bc0ca4c163a to your computer and use it in GitHub Desktop.
An extension that allows UICollectionViews to automatically register nib-based UICollectionViewCells when it dequeues them. Makes working with nib-based cells much easier.
import Foundation
import UIKit
protocol NibBased {
static var nibName: String { get }
}
extension NibBased {
static var nibName: String {
return String(describing: self)
}
}
extension UICollectionView {
private struct AssociatedKeys {
static var registeredNibBasedCells = "kRegisteredNibBasedCells"
}
//this allows us to add a stored property of type Set<String> to all UICollectionViews via an extension
var registeredNibBasedCells: Set<String>? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.registeredNibBasedCells) as? Set<String>
}
set {
if let newValue = newValue {
objc_setAssociatedObject(self, &AssociatedKeys.registeredNibBasedCells, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
func dequeueReusableCell<T: UICollectionViewCell>(ofType type: T.Type, for indexPath: IndexPath) -> T where T: NibBased {
if registeredNibBasedCells == nil {
registeredNibBasedCells = Set<String>()
}
guard let registeredCells = registeredNibBasedCells else {
fatalError("Unable to access the set of registered nib-based cells")
}
let className = type.nibName
if !registeredCells.contains(className) {
let nib = UINib(nibName: className, bundle: nil)
register(nib, forCellWithReuseIdentifier: className)
registeredNibBasedCells?.insert(className)
}
let dequeuedCell = dequeueReusableCell(withReuseIdentifier: className, for: indexPath)
guard let castedCell = dequeuedCell as? T else {
fatalError("Unable to cast dequeued cell to type '\(className)'")
}
return castedCell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment