Last active
September 8, 2017 18:21
-
-
Save joshuawright11/aa38237e8ad119c8af5f05193de41292 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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