Skip to content

Instantly share code, notes, and snippets.

@jimmythai
Last active June 11, 2018 08:29
Show Gist options
  • Select an option

  • Save jimmythai/fb46aafd2b8ab28d7d3de058f33e1baf to your computer and use it in GitHub Desktop.

Select an option

Save jimmythai/fb46aafd2b8ab28d7d3de058f33e1baf to your computer and use it in GitHub Desktop.
// ### Con's of the UITableView's `register` and `dequeue` methods
// - You have to use String for `reusableIdentifier`.
// - The interfaces for nib and class are different.
// - When you dequeue cells, you have to cast them as custom classes.
protocol Reusable: class {
static var reusableIdentifier: String { get }
}
extension Reusable {
static var reusableIdentifier: String {
return String(describing: self)
}
}
protocol NibReusable: Reusable {
static var nib: UINib { get }
}
extension NibReusable {
static var nib: UINib {
let nibName = String(describing: self)
return UINib(nibName: nibName, bundle: Bundle(for: self))
}
}
extension UITableView {
func register<T: Reusable>(_ reusableClass: T.Type) where T: UITableViewCell {
register(reusableClass, forCellReuseIdentifier: reusableClass.reusableIdentifier)
}
func register<T: NibReusable>(_ nibReusableClass: T.Type) where T: UITableViewCell {
register(nibReusableClass.nib, forCellReuseIdentifier: nibReusableClass.reusableIdentifier)
}
func register<T: Reusable>(_ reusableClass: T.Type) where T: UITableViewHeaderFooterView {
register(reusableClass, forHeaderFooterViewReuseIdentifier: reusableClass.reusableIdentifier)
}
func register<T: NibReusable>(_ nibReusableClass: T.Type) where T: UITableViewHeaderFooterView {
register(nibReusableClass.nib, forHeaderFooterViewReuseIdentifier: nibReusableClass.reusableIdentifier)
}
func dequeueReusableCell<T: Reusable>(_ reusableClass: T.Type) -> T where T: UITableViewCell {
guard let cell = dequeueReusableCell(withIdentifier: reusableClass.reusableIdentifier) as? T else {
fatalError("Unknown class type for cell, \(reusableClass)")
}
return cell
}
func dequeueReusableCell<T: Reusable>(_ reusableClass: T.Type, for indexPath: IndexPath) -> T where T: UITableViewCell {
guard let cell = dequeueReusableCell(withIdentifier: reusableClass.reusableIdentifier, for: indexPath) as? T else {
fatalError("Unknown class type for cell, \(reusableClass)")
}
return cell
}
func dequeueReusableHeaderFooterView<T: Reusable>(_ reusableClass: T.Type) -> T where T: UITableViewHeaderFooterView {
guard let headerFooterView = dequeueReusableHeaderFooterView(withIdentifier: reusableClass.reusableIdentifier) as? T else {
fatalError("Unknown class type for cell, \(reusableClass)")
}
return headerFooterView
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment