我創建了測驗專案來重現問題https://github.com/msnazarow/DiffarableTest
只需通過幾個步驟
- 創建新目標
- 創建
Base繼承UITableViewDiffableDataSource但UITableViewDelegate不實作UITableViewDelegate方法的類 - 在另一個目標(簡化的主要)繼承
Base類并實作任何UITableViewDelegate方法(例如didSelectRowAt) - 任何實施方法都不起作用
uj5u.com熱心網友回復:
您必須將類中的委托函式配置為BaseDataSource在子類中被覆寫。
所以,第一步,注釋掉你的didSelectRowAt函式extension MyDataSource:
extension MyDataSource {
// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// print("CELL SELECTED")
// }
}
并didSelectRowAt實施BaseDataSource:
open class BaseDataSource<T: Model & Hashable>: UITableViewDiffableDataSource<Int, T>, UITableViewDelegate {
public init(tableView: UITableView) {
super.init(tableView: tableView) { tableView, indexPath, model in
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! Configurable
cell.configure(with: model)
return cell as? UITableViewCell
}
}
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Base Cell Selected", indexPath)
}
}
當您運行應用程式并點擊第三行時,您應該會得到除錯輸出:
Base Cell Selected [0, 2]
要在您的子類中實作它,您可以覆寫它:
extension MyDataSource {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("MyDataSource Cell Selected", indexPath)
}
}
你會得到一個錯誤:Cannot override a non-dynamic class declaration from an extension ...所以讓它在BaseDataSource:
open class BaseDataSource<T: Model & Hashable>: UITableViewDiffableDataSource<Int, T>, UITableViewDelegate {
public init(tableView: UITableView) {
super.init(tableView: tableView) { tableView, indexPath, model in
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! Configurable
cell.configure(with: model)
return cell as? UITableViewCell
}
}
public dynamic func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Base Cell Selected", indexPath)
}
}
現在點擊第三行應該輸出:
MyDataSource Cell Selected [0, 2]
請注意,如果沒有子類委托,將呼叫didSelectRowAtin 。BaseDataSource另外,如果您希望某些代碼也可以在didSelectRowAtin 中運行BaseDataSource,您可以super從子類中呼叫:
extension MyDataSource {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
super.tableView(tableView, didSelectRowAt: indexPath)
print("MyDataSource Cell Selected", indexPath)
}
}
并選擇第三行輸出:
Base Cell Selected [0, 2]
MyDataSource Cell Selected [0, 2]
編輯
經過更多研究,一些人認為這是一個“錯誤”,因為它似乎在 Swift 版本之間發生了變化。
然而,一路走來的一大變化是 Swift 最初做了但不再推斷@objc. @objc當有必要添加到函式中時,例如在選擇器中使用時,每個人都會遇到這種情況。
所以,有兩種方法來處理這個......
首先,如上所示,為要在子類中覆寫的任何表視圖委托函式實作“什么都不做”函式。
聽起來您更喜歡的第二個選項是@objc在您的子類(或其擴展)中宣告該方法:
extension MyDataSource {
// add this line
@objc (tableView:didSelectRowAtIndexPath:)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("MyDataSource extension Cell Selected", indexPath)
}
}
現在你可以回到你的原始代碼,你只需要添加那一行來獲得所需的功能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/495620.html
標籤:IOS 迅速 合适的视图 uikit uitableviewdiffabledatasource
下一篇:在列印中使用未初始化的值
