Ios 注册并退出特定类型的UITableViewCell
UITableView是在objc已经“过时”且从未提及swift时构建的。在objc中,如果您将一个单元格出列以强制转换它,则无需进行任何操作,只要您有正确的单元格,您只需分配它,一切都会正常进行 随着斯威夫特的出现,仿制药的力量进入了iOS(和其他苹果)平台 现在我发现自己一次又一次地写了很多样板文件(定义一个标识符,转换单元格,使用强制展开致命错误…)Ios 注册并退出特定类型的UITableViewCell,ios,swift,uitableview,generics,Ios,Swift,Uitableview,Generics,UITableView是在objc已经“过时”且从未提及swift时构建的。在objc中,如果您将一个单元格出列以强制转换它,则无需进行任何操作,只要您有正确的单元格,您只需分配它,一切都会正常进行 随着斯威夫特的出现,仿制药的力量进入了iOS(和其他苹果)平台 现在我发现自己一次又一次地写了很多样板文件(定义一个标识符,转换单元格,使用强制展开致命错误…) 因此,我想知道是否有一些想法可以使代码更易于使用和更简洁。解决这个问题的简单方法是编写一个小的扩展 如果未注册的单元格已退出队列,此解决方
因此,我想知道是否有一些想法可以使代码更易于使用和更简洁。解决这个问题的简单方法是编写一个小的扩展 如果未注册的单元格已退出队列,此解决方案将导致致命错误。如果我们调用
dequeueReusableCell(withIdentifier:for:)
,如果我们没有注册该单元,这已经是iOS的默认行为
为了实现这一点,我们需要一种方法为任何类型的单元创建一个唯一标识符,我们将使用泛型注册和出列这些单元。如果您想让同一个单元格中的不同标识符退出队列,那么您必须退回到默认系统(从来没有这样做的必要)
因此,让我们创建一个名为UITableView+Tools.swift
(或您想命名的名称)的类
就这样。希望你喜欢这个主意。任何其他(更好或更差的@Saren)您的解决方案对单个
UITableViewCell
都很有效,但我对它做了一些增强,支持多个UITableViewCell
注册
UITableView+extension.swift
public protocol ClassNameProtocol {
static var className: String { get }
var className: String { get }
}
public extension ClassNameProtocol {
public static var className: String {
return String(describing: self)
}
public var className: String {
return type(of: self).className
}
}
extension NSObject: ClassNameProtocol {}
public extension UITableView {
public func register<T: UITableViewCell>(cellType: T.Type) {
let className = cellType.className
let nib = UINib(nibName: className, bundle: nil)
register(nib, forCellReuseIdentifier: className)
}
public func register<T: UITableViewCell>(cellTypes: [T.Type]) {
cellTypes.forEach { register(cellType: $0) }
}
public func dequeueReusableCell<T: UITableViewCell>(with type: T.Type, for indexPath: IndexPath) -> T {
return self.dequeueReusableCell(withIdentifier: type.className, for: indexPath) as! T
}
public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterType: T.Type) {
let className = HeaderFooterType.className
let nib = UINib(nibName: className, bundle: nil)
register(nib, forHeaderFooterViewReuseIdentifier: className)
}
public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterTypes: [T.Type]) {
HeaderFooterTypes.forEach { registerHeaderFooter(HeaderFooterType: $0) }
}
}
注意:请确保您的UITableviewCell
的类名和可重用ID应该相同。
func viewDidLoad {
...
tableView.register(MyCustomCell.self)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = dequeueReusableCell(forType: MyCustomCell.self, for: indexPath)
cell.viewModel = cellModel(for: indexPath)
return cell
}
public protocol ClassNameProtocol {
static var className: String { get }
var className: String { get }
}
public extension ClassNameProtocol {
public static var className: String {
return String(describing: self)
}
public var className: String {
return type(of: self).className
}
}
extension NSObject: ClassNameProtocol {}
public extension UITableView {
public func register<T: UITableViewCell>(cellType: T.Type) {
let className = cellType.className
let nib = UINib(nibName: className, bundle: nil)
register(nib, forCellReuseIdentifier: className)
}
public func register<T: UITableViewCell>(cellTypes: [T.Type]) {
cellTypes.forEach { register(cellType: $0) }
}
public func dequeueReusableCell<T: UITableViewCell>(with type: T.Type, for indexPath: IndexPath) -> T {
return self.dequeueReusableCell(withIdentifier: type.className, for: indexPath) as! T
}
public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterType: T.Type) {
let className = HeaderFooterType.className
let nib = UINib(nibName: className, bundle: nil)
register(nib, forHeaderFooterViewReuseIdentifier: className)
}
public func registerHeaderFooter<T: UITableViewHeaderFooterView>(HeaderFooterTypes: [T.Type]) {
HeaderFooterTypes.forEach { registerHeaderFooter(HeaderFooterType: $0) }
}
}
fileprivate let arrCells = [ContactTableViewCell.self,ContactDetailsCell.self]
self.register(cellTypes: arrCells)