Skip to content

Instantly share code, notes, and snippets.

@xmollv
Last active April 7, 2019 08:39
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 xmollv/c051e7814bb83bf67fea2506fb6afe82 to your computer and use it in GitHub Desktop.
Save xmollv/c051e7814bb83bf67fea2506fb6afe82 to your computer and use it in GitHub Desktop.
Reusable generic Cells. It only works with cells created with a .XIB file.
/// This protocol only aggregates the needed properties for the extensions to work and avoid duplicated code.
private protocol Reusable: class {
/// Returns `String(describing: self)` to be used as the `reuseIdentifier`.
static var reuseIdentifier: String { get }
/// Returns the UINib using the `String(describing: self)` as the name of the NIB.
static var nib: UINib { get }
}
private extension Reusable {
static var reuseIdentifier: String {
return String(describing: self)
}
static var nib: UINib {
return UINib(nibName: String(describing: self), bundle: Bundle(for: self))
}
}
extension UITableViewCell: Reusable {}
extension UITableView {
/// Registers a `UITableViewCell` using it's own `reuseIdentifier`. The `UITableViewCell` must be created using
/// a `.xib` file with the same name, otherwise it will crash.
func register<Cell: UITableViewCell>(_: Cell.Type) {
self.register(Cell.nib, forCellReuseIdentifier: Cell.reuseIdentifier)
}
/// Dequeues a `UITableViewCell` and casts it to the expected type at the call site.
func dequeueReusableCell<Cell: UITableViewCell>(for indexPath: IndexPath) -> Cell {
guard let cell = self.dequeueReusableCell(withIdentifier: Cell.reuseIdentifier, for: indexPath) as? Cell else {
fatalError("Unable to dequeue a \(String(describing: Cell.self)) cell.")
}
return cell
}
}
extension UICollectionViewCell: Reusable {}
extension UICollectionView {
/// Registers a `UICollectionViewCell` using it's own `reuseIdentifier`. The `UICollectionViewCell` must be created using
/// a `.xib` file with the same name, otherwise it will crash.
func register<Cell: UICollectionViewCell>(_: Cell.Type) {
self.register(Cell.nib, forCellWithReuseIdentifier: Cell.reuseIdentifier)
}
/// Dequeues a `UICollectionViewCell` and casts it to the expected type at the call site.
func dequeueReusableCell<Cell: UICollectionViewCell>(for indexPath: IndexPath) -> Cell {
guard let cell = self.dequeueReusableCell(withReuseIdentifier: Cell.reuseIdentifier, for: indexPath) as? Cell else {
fatalError("Unable to dequeue a \(String(describing: Cell.self)) cell.")
}
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment