Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Strongly Typed UITableViewCell allocation in Swift
import Foundation
import UIKit
/// MARK: - This protocol is used to allows cell to be dequeued with strong type
public protocol DequeuableProtocol: class {
/// Return the nib name in which the dequeuable resource is located
/// You must implement it if your cell is located in a separate xib file
/// (not for storyboard).
/// In this case you should call `table.register(CellClass.self)` before
/// using it in your code.
/// Default implementation returns the name of the class itself.
static var dequeueNibName: String { get }
/// This is the identifier used to queue/dequeue the cell.
/// You don't need to override it; default implementation return the name
/// of the cell class itself as identifier.
static var dequeueIdentifier: String { get }
}
// MARK: - Default implementation of the protocol
extension DequeuableProtocol where Self: UIView {
/// Return the same name of the class with module name as prefix ('MyApp.MyCell')
public static var dequeueIdentifier: String {
return NSStringFromClass(self)
}
/// Return the name of the nib, it return the same name of the cell class itself
public static var dequeueNibName: String {
return NSStringFromClass(self).components(separatedBy: ".").last!
}
}
// MARK: - Table View Registration and Dequeue
public extension UITableView {
/// Register a cell from external xib into a table instance.
///
/// - Parameter _: cell class
public func register<T: UITableViewCell>(_: T.Type) where T: DequeuableProtocol {
let bundle = Bundle(for: T.self)
let nib = UINib(nibName: T.dequeueNibName, bundle: bundle)
self.register(nib, forCellReuseIdentifier: T.dequeueIdentifier)
}
/// Dequeue a cell instance strongly typed.
///
/// - Parameter indexPath: index path
/// - Returns: instance
public func dequeueReusableCell<T: UITableViewCell>(forIndexPath indexPath: NSIndexPath) -> T where T: DequeuableProtocol {
guard let cell = dequeueReusableCell(withIdentifier: T.dequeueIdentifier, for: indexPath as IndexPath) as? T else {
fatalError("Cannot dequeue: \(T.self) with identifier: \(T.dequeueIdentifier)")
}
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment