Last active
March 7, 2019 01:55
-
-
Save asmallteapot/07f365c56cebdb6835eb to your computer and use it in GitHub Desktop.
An attempt at making UITableView cell reuse a bit more idiomatic in Swift.
This file contains 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
@objc class ExampleTableCell: UITableViewCell, ReuseableObject, NibLoadable {} | |
@objc class ExampleViewController: UITableViewController { | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override init(style: UITableViewStyle) { | |
super.init(style: style) | |
self.tableView.registerCellType(ExampleTableCell) | |
} | |
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { | |
let cell: ExampleTableCell = tableView.dequeueCellForIndexPath(indexPath) | |
// configure the cell ... | |
return cell | |
} | |
} |
This file contains 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
extension UITableView { | |
// I want to be able to write typealiases with constraints to simplify method signatures | |
typealias ReusableCell = UITableViewCell where ReusableObject | |
typealias NibLoadableCell = ReusableCell where NibLoadable | |
func registerCellType(cellType: ReusableCell.Type) { | |
self.registerClass(cellType, forCellReuseIdentifier: cellType.ReuseIdentifier) | |
} | |
func registerNibForCellType(cellType: NibLoadableCell.Type) { | |
self.registerNib(cellType.Nib, forCellReuseIdentifier: cellType.ReuseIdentifier) | |
} | |
} |
This file contains 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
protocol NibLoadable { | |
static var NibName: String { get } | |
static var NibBundle: NSBundle? { get } | |
} | |
extension NibLoadable { | |
static var Nib: UINib { | |
get { | |
return UINib(nibName: self.NibName, bundle: self.NibBundle) | |
} | |
} | |
} | |
extension NibLoadable { | |
static var NibName: String { | |
get { | |
return String(self) | |
} | |
} | |
static var NibBundle: NSBundle? { | |
get { | |
return nil | |
} | |
} | |
} |
This file contains 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
protocol ReusableObject { | |
static var ReuseIdentifier: String { get } | |
} | |
extension ReusableObject { | |
static var ReuseIdentifier: String { | |
get { | |
return String(self) | |
} | |
} | |
} |
This file contains 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
extension UITableView { | |
typealias Cell = UITableViewCell | |
func registerCellType<C: Cell where C: ReusableObject>(cellType: C.Type) { | |
self.registerClass(cellType, forCellReuseIdentifier: cellType.ReuseIdentifier) | |
} | |
func registerNibForCellType<C: Cell where C: ReusableObject, C: NibLoadable>(cellType: C.Type) { | |
self.registerNib(cellType.Nib, forCellReuseIdentifier: cellType.ReuseIdentifier) | |
} | |
func dequeueCellOfType<C: Cell where C: ReusableObject>(cellType: C.Type, forIndexPath indexPath: NSIndexPath) -> C? { | |
return self.dequeueReusableCellWithIdentifier(cellType.ReuseIdentifier, forIndexPath: indexPath) as? C | |
} | |
func dequeueCellForIndexPath<C: Cell where C: ReusableObject>(indexPath: NSIndexPath) -> C? { | |
return self.dequeueReusableCellWithIdentifier(C.ReuseIdentifier, forIndexPath: indexPath) as? C | |
} | |
} |
This file contains 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
extension UITableView { | |
// "Scrubber" == "Section Index" in UIKit/ObjC terms | |
struct ScrubberConfig { | |
let minimumDisplayRowCount: Int | |
let textColor: UIColor? | |
let backgroundColor: UIColor? | |
let scrubbingBackgroundColor: UIColor? | |
init(minimumRows: Int = 0, textColor: UIColor? = nil, backgroundColor: UIColor? = nil, scrubbingBackgroundColor: UIColor? = nil) { | |
self.minimumDisplayRowCount = minimumRows | |
self.textColor = textColor | |
self.backgroundColor = backgroundColor | |
self.scrubbingBackgroundColor = scrubbingBackgroundColor | |
} | |
} | |
var scrubberConfig: ScrubberConfig { | |
get { | |
return ScrubberConfig(minimumRows: self.sectionIndexMinimumDisplayRowCount, textColor: self.sectionIndexColor, backgroundColor: self.sectionIndexBackgroundColor, scrubbingBackgroundColor: self.sectionIndexTrackingBackgroundColor) | |
} | |
set(newValue) { | |
self.sectionIndexMinimumDisplayRowCount = newValue.minimumDisplayRowCount | |
self.sectionIndexColor = newValue.textColor | |
self.sectionIndexBackgroundColor = newValue.backgroundColor | |
self.sectionIndexTrackingBackgroundColor = newValue.scrubbingBackgroundColor | |
} | |
} | |
} |
This file contains 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
// not totally happy with this nickname for the concept | |
extension UITableView { | |
typealias SectionView = UITableViewHeaderFooterView | |
func registerSectionViewType<V: SectionView where V: ReusableObject>(viewType: V.Type) { | |
self.registerClass(viewType, forHeaderFooterViewReuseIdentifier: viewType.ReuseIdentifier) | |
} | |
func registerNibForSectionViewType<V: SectionView where V: ReusableObject, V: NibLoadable>(viewType: V.Type) { | |
self.registerNib(viewType.Nib, forHeaderFooterViewReuseIdentifier: viewType.ReuseIdentifier) | |
} | |
func dequeueSectionViewOfType<V: SectionView where V: ReusableObject>(viewType: V.Type) -> V? { | |
return self.dequeueReusableHeaderFooterViewWithIdentifier(viewType.ReuseIdentifier) as? V | |
} | |
} |
This file contains 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
extension UITableViewCell { | |
typealias SeparatorStyle = UITableViewCellSeparatorStyle | |
} | |
extension UITableView { | |
// TODO: rename "config" to something nicer | |
struct SeparatorConfig { | |
let style: Cell.SeparatorStyle | |
let color: UIColor? | |
let inset: UIEdgeInsets | |
let effect: UIVisualEffect? | |
static func Default() -> SeparatorConfig { | |
return self.init(style: .SingleLine, color: nil, inset: UIEdgeInsetsZero, effect: nil) | |
} | |
} | |
var separatorConfig: SeparatorConfig { | |
get { | |
// MARK: WARNING: force unwrap | |
return SeparatorConfig(style: self.separatorStyle, color: self.separatorColor, inset: self.separatorInset, effect: self.separatorEffect) | |
} | |
set(newValue) { | |
self.separatorStyle = newValue.style | |
self.separatorColor = newValue.color | |
self.separatorInset = newValue.inset | |
self.separatorEffect = newValue.effect | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment