[英]Swift Generic Protocol Class Type in Array
我們已經實現了一個協議, Reusable
,以緩解UITableView
注冊/出隊的實現,為我們UITableViewCell
秒。
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 tableView: UITableView = UITableView()
tableView.register(TestTableViewCell.self)
tableView.register(AnotherTableViewCell.self)
一切都運行良好,但我們想將這些類型移動到一個數組,以便訂購。 這就是我們陷入困境的地方,這不起作用:
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
編寫一個擴展,使其符合Reusable
協議,不要將單元格轉換為任何類型:
extension UITableViewCell: Reusable {}
Reusable
協議實現。
祝好運 :)
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 { }
extension UITableView {
func register<T: UITableViewCell & Reusable>(_: T.Type) {
register(UINib(nibName: T.defaultIdentifier, bundle: nil), forCellReuseIdentifier: T.defaultIdentifier)
}
}
let tableView: UITableView = UITableView()
tableView.register(TestTableViewCell.self)
let viewCells = [TestTableViewCell.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)
}
此代碼成功執行。
希望你對此感到高興。 關鍵是協議中的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)
}
}
let viewCells: [Reusable.Type] = [TestTableViewCell.self, AnotherTestTableViewCell.self]
for viewCell in viewCells {
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)
}
}
並像這樣使用它
let tableView: UITableView = UITableView()
let cellsArray = [Test.self, Test1.self, Test2.self]
for cell in cellsArray {
tableView.registerCell(cellType: cell)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.