Skip to content

Instantly share code, notes, and snippets.

@xxKRASHxx
Created May 7, 2021 09:27
Show Gist options
  • Save xxKRASHxx/94c619d42053951b1f81fa70cbe02731 to your computer and use it in GitHub Desktop.
Save xxKRASHxx/94c619d42053951b1f81fa70cbe02731 to your computer and use it in GitHub Desktop.
import UIKit
public protocol Reusable {
static var reuseIdentifier: String { get }
}
public extension Reusable {
static var reuseIdentifier: String {
return String(describing: self)
}
}
extension UITableViewCell: Reusable {}
extension UICollectionViewCell: Reusable {}
extension UITableViewHeaderFooterView: Reusable {}
public extension UITableView {
final func register<T: UITableViewCell>(cellType: T.Type) {
register(
cellType.self,
forCellReuseIdentifier: cellType.reuseIdentifier
)
}
final func dequeueReusableCell<T: UITableViewCell>(
for indexPath: IndexPath,
cellType: T.Type = T.self
) -> T {
guard let cell = self.dequeueReusableCell(
withIdentifier: cellType.reuseIdentifier,
for: indexPath) as? T
else {
assertionFailure(
"""
Failed to dequeue a cell with identifier \(cellType.reuseIdentifier)
matching type \(cellType.self).
Check that the reuseIdentifier is set properly in your XIB/Storyboard
and that you registered the cell beforehand
"""
)
return T()
}
return cell
}
final func register<T: UITableViewHeaderFooterView>(headerFooterViewType: T.Type) {
register(
headerFooterViewType.self,
forHeaderFooterViewReuseIdentifier: headerFooterViewType.reuseIdentifier
)
}
final func dequeueReusableHeaderFooterView<T: UITableViewHeaderFooterView>(
_ viewType: T.Type = T.self
) -> T? {
guard let view = dequeueReusableHeaderFooterView(
withIdentifier: viewType.reuseIdentifier) as? T?
else {
assertionFailure(
"""
Failed to dequeue a header/footer with identifier \(viewType.reuseIdentifier)
matching type \(viewType.self).
Check that the reuseIdentifier is set properly in your XIB/Storyboard
and that you registered the header/footer beforehand
"""
)
return T()
}
return view
}
}
public extension UICollectionView {
final func register<T: UICollectionViewCell>(cellType: T.Type) {
register(
cellType.self,
forCellWithReuseIdentifier: cellType.reuseIdentifier
)
}
final func dequeueReusableCell<T: UICollectionViewCell>(
for indexPath: IndexPath,
cellType: T.Type = T.self
) -> T {
guard let cell = dequeueReusableCell(
withReuseIdentifier: cellType.reuseIdentifier,
for: indexPath) as? T else {
assertionFailure(
"""
Failed to dequeue a cell with identifier \(cellType.reuseIdentifier)
matching type \(cellType.self).
Check that the reuseIdentifier is set properly in your XIB/Storyboard
and that you registered the cell beforehand
"""
)
return T()
}
return cell
}
final func register<T: UICollectionReusableView>(
supplementaryViewType: T.Type,
ofKind elementKind: String
) where T: Reusable {
register(
supplementaryViewType.self,
forSupplementaryViewOfKind: elementKind,
withReuseIdentifier: supplementaryViewType.reuseIdentifier
)
}
final func dequeueReusableSupplementaryView<T: UICollectionReusableView>(
ofKind elementKind: String,
for indexPath: IndexPath,
viewType: T.Type = T.self
) -> T where T: Reusable {
let view = dequeueReusableSupplementaryView(
ofKind: elementKind,
withReuseIdentifier: viewType.reuseIdentifier,
for: indexPath
)
guard let typedView = view as? T else {
assertionFailure(
"""
Failed to dequeue a supplementary view with identifier \(viewType.reuseIdentifier)
matching type \(viewType.self).
Check that the reuseIdentifier is set properly in your XIB/Storyboard
and that you registered the supplementary view beforehand
"""
)
return T()
}
return typedView
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment