我已经为UITableView创建了一个扩展,并希望在运行时获得正确的reuseIdentifier,但我不能:
extension UITableView {
func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T {
let s = T.reuseIdentifier变量"s“总是包含"UITableViewCell”,而不是我在故事板中指定的名称。
发布于 2019-06-01 18:36:16
不要紧,整个方法
extension UITableView {
func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T {
return self.dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as! T
}
}应该是正常工作的。
另一种选择是协议扩展和static方法,只需采用UITableViewCell子类中的协议。
protocol Reusable {
associatedtype CellType : UITableViewCell = Self
static var cellIdentifier : String { get }
static func dequeueReusableCell(in tableView : UITableView, for indexPath: IndexPath) -> CellType
}
extension Reusable where Self : UITableViewCell {
static var cellIdentifier : String {
return String(describing: Self.self)
}
static func dequeueReusableCell(in tableView : UITableView, for indexPath: IndexPath) -> CellType {
return tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CellType
}
}并将其称为
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = MyTableViewCell.dequeueReusableCell(in: tableView, for: indexPath)
...发布于 2019-06-01 17:57:02
我的处理方法如下所示。
I创建了一个协议,该协议将类型声明为可从nib:加载
// 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)我做了这个available in a gist here。
https://stackoverflow.com/questions/56405532
复制相似问题