Ios 数组中的Swift通用协议类类型
我们已经为我们的Ios 数组中的Swift通用协议类类型,ios,swift,swift-protocols,Ios,Swift,Swift Protocols,我们已经为我们的UITableViewCell实现了一个协议,reusible,以简化UITableView的注册/出列实现 protocol Reusable: class { static var defaultIdentifier: String { get } } extension Reusable where Self: UITableViewCell { static var defaultIdentifier: String { return S
UITableViewCell
实现了一个协议,reusible
,以简化UITableView
的注册/出列实现
protocol Reusable: class {
static var defaultIdentifier: String { get }
}
extension Reusable where Self: UITableViewCell {
static var defaultIdentifier: String {
return String(describing: self)
}
}
class TestTableViewCell: UITableViewCell, Reusable { }
class AnotherTestTableViewCell: UITableViewCell, Reusable { }
然后,UITableView
有一个扩展,比如:
extension UITableView {
func register<T: UITableViewCell & Reusable>(_: T.Type) {
register(UINib(nibName: T.defaultIdentifier, bundle: nil), forCellReuseIdentifier: T.defaultIdentifier)
}
}
一切都很好,但我们希望将这些类型移动到一个数组中,以便进行排序。这就是我们被困的地方,这不起作用:
let viewCells = [TestTableViewCell.self, AnotherTestTableViewCell.self]
// Without type annotation, it's [UITableViewCell.Type]
// And the error is: Instance method 'register' requires that 'UITableViewCell' conform to 'Reusable'
for viewCell in viewCells {
tableView.register(viewCell)
}
我们还尝试:
let viewCells: [Reusable.Type] = ...
// Error: Cannot invoke 'register' with an argument list of type '(Reusable.Type)'
还包括:
let viewCells: [(UITableViewCell & Reusable).Type] = ...
// Error: Instance method 'register' requires that 'UITableViewCell' conform to 'Reusable'
有没有一种方法可以将符合协议的类类型信息存储在一个数组中以实现这一功能?只需为
UITableViewCell
编写一个扩展,使其符合可重用
协议,并且不将单元格强制转换为任何类型:
extension UITableViewCell: Reusable {}
另外,您还可以在iOS上检查最流行的
可重用
协议实现
祝你好运:)
协议可重用:类{
静态变量defaultIdentifier:字符串{get}
}
扩展可重用where Self:UITableViewCell{
静态变量defaultIdentifier:字符串{
返回字符串(描述:self)
}
}
类TestTableViewCell:UITableViewCell,可重用{}
扩展UITableView{
func寄存器(uUt:T.Type){
寄存器(UINib(nibName:T.defaultIdentifier,bundle:nil),强制重用标识符:T.defaultIdentifier)
}
}
让tableView:UITableView=UITableView()
寄存器(TestTableViewCell.self)
让viewCells=[TestTableViewCell.self]
//如果没有类型注释,则为[UITableViewCell.type]
//错误是:实例方法“register”要求“UITableViewCell”符合“Reusables”
对于viewCells中的viewCell{
tableView.register(viewCell)
}
此代码成功执行。只需使用此表视图扩展方法注册单元格即可
extension UITableView {
func registerCell<T: UITableViewCell>(cellType: T.Type) {
let nib = UINib(nibName: String(describing: cellType.self), bundle: nil)
let reuseIdentifier = String(describing: cellType.self)
self.register(nib, forCellReuseIdentifier: reuseIdentifier)
}
}
希望你对此感到高兴。协议中的关键字是
Self
关键字
protocol Reusable: class {
static var defaultIdentifier: String { get }
static func register(tableView: UITableView)
}
extension Reusable where Self: UITableViewCell {
static var defaultIdentifier: String {
return String(describing: self)
}
static func register(tableView: UITableView) {
tableView.register(UINib(nibName: Self.defaultIdentifier, bundle: nil), forCellReuseIdentifier: Self.defaultIdentifier)
}
}
extension UITableView {
func register(_ reusable: Reusable.Type) {
reusable.register(tableView: self)
}
}
我建议您阅读以下链接:
类型“UITableViewCell.type”的值与强制中的“UITableViewCell&reusible”不一致
而不是在注释中讨论。让我们来做一个聊天摘要:它起作用,但是我们真的不想将协议扩展到每个UITableViewCell
@EDUsta为什么不扩展每个UITableViewCell
以符合协议?@JeremyP公平的问题是,有些UITableViewCell
类没有单独的nib,或者与其名称不匹配,因此,我们还没有准备好进行转换,相反,我们正在一个接一个地进行,并了解过程(哪些单元格已准备好/未准备好)。感谢您的回答,但它只是忽略了协议,这就是我们这样做的全部原因。@EDUsta听起来很棒。如果你不介意的话,请接受我的回答
extension UITableView {
func registerCell<T: UITableViewCell>(cellType: T.Type) {
let nib = UINib(nibName: String(describing: cellType.self), bundle: nil)
let reuseIdentifier = String(describing: cellType.self)
self.register(nib, forCellReuseIdentifier: reuseIdentifier)
}
}
let tableView: UITableView = UITableView()
let cellsArray = [Test.self, Test1.self, Test2.self]
for cell in cellsArray {
tableView.registerCell(cellType: cell)
}
protocol Reusable: class {
static var defaultIdentifier: String { get }
static func register(tableView: UITableView)
}
extension Reusable where Self: UITableViewCell {
static var defaultIdentifier: String {
return String(describing: self)
}
static func register(tableView: UITableView) {
tableView.register(UINib(nibName: Self.defaultIdentifier, bundle: nil), forCellReuseIdentifier: Self.defaultIdentifier)
}
}
extension UITableView {
func register(_ reusable: Reusable.Type) {
reusable.register(tableView: self)
}
}
let viewCells: [Reusable.Type] = [TestTableViewCell.self, AnotherTestTableViewCell.self]
for viewCell in viewCells {
tableView.register(viewCell)
}