Skip to content

Instantly share code, notes, and snippets.

@joshuawright11
Last active September 8, 2017 18:21
Show Gist options
  • Select an option

  • Save joshuawright11/aa38237e8ad119c8af5f05193de41292 to your computer and use it in GitHub Desktop.

Select an option

Save joshuawright11/aa38237e8ad119c8af5f05193de41292 to your computer and use it in GitHub Desktop.
import UIKit
struct TableViewRow {
var type: UITableViewCell.Type
var cellConfiguration: ((_ cell: UITableViewCell) -> Void)?
var action: (() -> Void)?
init<T: UITableViewCell>(type: T.Type,
cellConfiguration: ((_ cell: T) -> Void)?,
action: (() -> Void)?) {
self.type = type
// Hacky way to avoid compiler error of mismatched closure types. The
// error should never trigger.
func wrapper(cell: UITableViewCell) {
guard let cell = cell as? T else { fatalError("Somehow the dequeued cell had a different type than expected. This shouldn't be possible.") }
cellConfiguration?(cell)
}
self.cellConfiguration = wrapper
self.action = action
}
}
typealias TableViewSection = (title: String, rows: [TableViewRow])
// Simple protocol and extensions to add a `cellIdentifier` to every
// UITableViewCell
//
// If different reuse identifiers are needed for multiple cells of the same
// class custom cellIdentifiers will need to be used.
protocol Reusable: class {
static var cellIdentifier: String { get }
}
extension Reusable {
static var cellIdentifier: String {
return NSStringFromClass(self)
}
}
extension UIView: Reusable {}
// Generic support for cell registering and dequeueing
protocol NibLoadableView: class {
static var nibName: String { get }
}
extension NibLoadableView where Self: UIView {
static var nibName: String {
guard let className = NSStringFromClass(self).components(separatedBy: ".").last else {
fatalError("Couldn't get a name for this class.")
}
return className
}
}
extension UITableView {
func register<T: UITableViewCell>(_: T.Type) {
register(T.self, forCellReuseIdentifier: T.cellIdentifier)
}
func register<T: UITableViewCell>(_: T.Type) where T: NibLoadableView {
let nib = UINib(nibName: T.nibName, bundle: Bundle(for: T.self))
register(nib, forCellReuseIdentifier: T.cellIdentifier)
}
func dequeueReusableCell<T: UITableViewCell>(forIndexPath indexPath: IndexPath) -> T {
guard let cell = dequeueReusableCell(withIdentifier: T.cellIdentifier, for: indexPath) as? T else {
fatalError("Could not dequeue cell with identifier: \(T.cellIdentifier)")
}
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment