Мой способ справиться с этим заключается в следующем.
Я создаю протокол, который объявляет тип загружаемым из пера:
// MARK: Nib Loadable
public protocol NibLoadable {
/// The name of the .xib file in which this view is defined.
static var nibName: String { get }
}
// MARK: Nib Loadable Convenience
public extension NibLoadable where Self: UIView {
static var nibName: String { return NSStringFromClass(self).components(separatedBy: ".").last! }
}
Я создаю другой тип, который объявляет тип как повторно используемый и автоматически согласовывает ячейки представления таблицы и коллекции:
// MARK: Reusable View
/**
Indicates that a view can be reused provided it matches a provided identifier.
*/
public protocol ReusableView: class {
/// The identifier for this type of reusable view.
static var defaultReuseIdentifier: String { get }
}
// MARK: Reusable View Convenience
public extension ReusableView where Self: UIView {
static var defaultReuseIdentifier: String { return NSStringFromClass(self).components(separatedBy: ".").last! }
}
extension UICollectionViewCell: ReusableView { }
extension UITableViewCell: ReusableView { }
Затем я создаю простой способ регистрации такой ячейки:
// MARK: Registration
public extension UICollectionView {
func register<T: UICollectionViewCell>(_: T.Type) {
register(T.self, forCellWithReuseIdentifier: T.defaultReuseIdentifier)
}
func register<T: UICollectionViewCell>(_: T.Type) where T: NibLoadable {
let bundle = Bundle(for: T.self)
let nib = UINib(nibName: T.nibName, bundle: bundle)
register(nib, forCellWithReuseIdentifier: T.defaultReuseIdentifier)
}
}
public extension UITableView {
func register<T: UITableViewCell>(_: T.Type) {
register(T.self, forCellReuseIdentifier: T.defaultReuseIdentifier)
}
func register<T: UITableViewCell>(_: T.Type) where T: NibLoadable {
let bundle = Bundle(for: T.self)
let nib = UINib(nibName: T.nibName, bundle: bundle)
register(nib, forCellReuseIdentifier: T.defaultReuseIdentifier)
}
}
Наконец-то у меня есть удобный способ удаления этих ячеек:
// MARK: Dequeuing
public extension UICollectionView {
func dequeue<T: UICollectionViewCell>(for indexPath: IndexPath) -> T {
guard let cell = dequeueReusableCell(withReuseIdentifier: T.defaultReuseIdentifier, for: indexPath) as? T else {
fatalError("Could not dequeue cell with identifier: \(T.defaultReuseIdentifier)")
}
return cell
}
}
public extension UITableView {
func dequeue<T: UITableViewCell>(for indexPath: IndexPath) -> T {
guard let cell = dequeueReusableCell(withIdentifier: T.defaultReuseIdentifier, for: indexPath) as? T else {
fatalError("Could not dequeue cell with identifier: \(T.defaultReuseIdentifier)")
}
return cell
}
}
При использовании приложения я делаю идентификатор повторного использования для любой ячейки с именем класса. Затем я изменяю ячейку следующим образом:
extension PersonalDetailTableViewCell: NibLoadable { }
Владелец табличного представления зарегистрирует ячейку в viewDidLoad()
:
tableView.register(PersonalDetailTableViewCell.self)
Внутри функции cellForRow
я удалю должным образом:
let cell: PersonalDetailTableViewCell = tableView.dequeue(for: indexPath)
Я сделал это доступным в гисте здесь .