Skip to content

Instantly share code, notes, and snippets.

@eMdOS
Created November 1, 2018 14:21
Show Gist options
  • Save eMdOS/820e3cdf31fb7a24973b8fc976b94fa0 to your computer and use it in GitHub Desktop.
Save eMdOS/820e3cdf31fb7a24973b8fc976b94fa0 to your computer and use it in GitHub Desktop.
Table/Collection Views - Generic Cell Registration & Dequeuing
import UIKit
public protocol NibNameableView: class {
static var nibName: String { get }
}
extension NibNameableView where Self: UIView {
public static var nibName: String {
return String(describing: self)
}
}
import UIKit
public protocol ReusableView: class {
static var reusableIdentifier: String { get }
}
extension ReusableView where Self: UIView {
public static var reusableIdentifier: String {
return String(describing: self)
}
}
import UIKit
extension UICollectionView {
public enum SupplementaryViewKind {
case header
case footer
public var rawValue: String {
switch self {
case .header:
return UICollectionView.elementKindSectionHeader
case .footer:
return UICollectionView.elementKindSectionFooter
}
}
}
public func register<Cell: UICollectionViewCell>(cell: Cell.Type, inBundle bundle: Bundle) where Cell: ReusableView, Cell: NibNameableView {
let nib = UINib(nibName: Cell.nibName, bundle: bundle)
register(nib, forCellWithReuseIdentifier: Cell.reusableIdentifier)
}
public func register<View: UICollectionReusableView>(view: View.Type, inBundle bundle: Bundle, asSupplementaryViewKind kind: SupplementaryViewKind) where View: ReusableView, View: NibNameableView {
let nib = UINib(nibName: View.nibName, bundle: bundle)
register(nib, forSupplementaryViewOfKind: kind.rawValue, withReuseIdentifier: View.reusableIdentifier)
}
}
extension UICollectionView {
public func dequeueReusableCell<Cell: UICollectionViewCell>(forIndexPath indexPath: IndexPath) -> Cell where Cell: ReusableView {
guard let cell = dequeueReusableCell(withReuseIdentifier: Cell.reusableIdentifier, for: indexPath) as? Cell else {
fatalError("Could not dequeue cell with identifier: \(Cell.reusableIdentifier)")
}
return cell
}
public func dequeueReusableSupplementaryView<View: UICollectionReusableView>(ofKind kind: SupplementaryViewKind, forIndexPath indexPath: IndexPath) -> View where View: ReusableView {
guard let view = dequeueReusableSupplementaryView(ofKind: kind.rawValue, withReuseIdentifier: View.reusableIdentifier, for: indexPath) as? View else {
fatalError("Could not dequeue view with identifier: \(View.reusableIdentifier)")
}
return view
}
}
import UIKit
extension UITableView {
public func register<Cell: UITableViewCell>(cell: Cell.Type, inBundle bundle: Bundle) where Cell: ReusableView, Cell: NibNameableView {
let nib = UINib(nibName: Cell.nibName, bundle: bundle)
register(nib, forCellReuseIdentifier: Cell.reusableIdentifier)
}
public func register<View: UITableViewHeaderFooterView>(headerFooterView: View.Type, inBundle bundle: Bundle) where View: ReusableView, View: NibNameableView {
let nib = UINib(nibName: View.nibName, bundle: bundle)
register(nib, forHeaderFooterViewReuseIdentifier: View.reusableIdentifier)
}
}
extension UITableView {
public func dequeueReusableCell<Cell: UITableViewCell>(forIndexPath indexPath: IndexPath) -> Cell where Cell: ReusableView {
guard let cell = dequeueReusableCell(withIdentifier: Cell.reusableIdentifier, for: indexPath) as? Cell else {
fatalError("Could not dequeue cell with identifier: \(Cell.reusableIdentifier)")
}
return cell
}
public func dequeueReusableHeaderFooterView<View: UITableViewHeaderFooterView>() -> View where View: ReusableView {
guard let view = dequeueReusableHeaderFooterView(withIdentifier: View.reusableIdentifier) as? View else {
fatalError("Could not dequeue header/footer view with identifier: \(View.reusableIdentifier)")
}
return view
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment