如何使用单独的 UITableViewDataSource class 管理#selector?
How to manage #selector with separate UITableViewDataSource class?
我有一个单独的 class 用于 UITableViewDataSource
我的 UITableView
import UIKit
class CardDataSource: NSObject, UITableViewDataSource {
//MARK:- Property
var medialObjects: [MediaCardObject]?
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
var viewController: AddNewVC?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return medialObjects?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let obj = medialObjects![indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "MediaTextTableViewCell") as! MediaTextTableViewCell
cell.btnDelete.tag = indexPath.row
cell.btnDelete.addTarget(self, action: #selector(AddNewVC.deleteItem(sender:)), for: .touchUpInside)
cell.tfCardText.text = obj.path
cell.tfCardText.tag = indexPath.row
cell.tfCardText.returnKeyType = .done
cell.tfCardText.delegate = viewController
cell.selectionStyle = .none
return cell
}
}
数据在我的 UITableView
上加载正常,但问题是当我点击删除按钮时它崩溃并显示
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MediaCards.CardDataSource
deleteItemWithSender:]: unrecognized selector sent to instance
0x600003394cc0'
我也试过了
cell.btnDelete.addTarget(self, action: #selector(viewController?.deleteItem(sender:)), for: .touchUpInside)
这里是AddNewVC
中的删除方法
//MARK:- Delete
@objc func deleteItem(sender: UIButton) {
let selectedIndex = sender.tag
deleteObjectIndexPath = IndexPath(row: selectedIndex, section: 0)
confirmDelete()
}
并在 AddNewVC
class
var tblDataSource = CardDataSource()
override func viewDidLoad() {
super.viewDidLoad()
tblDataSource.viewController = self
tblMediaCards.dataSource = tblDataSource
if forEdit {
let cards = mediaObject?.cards?.allObjects as! [MediaCard]
for obj in cards {
let mediaCardObj = MediaCardObject.init(type: obj.type ?? "", path: obj.path ?? "", index: Int(obj.index))
self.medialObjects.append(mediaCardObj)
}
medialObjects = medialObjects.sorted(by: { [=14=].index! < .index! })
tblDataSource.medialObjects = medialObjects
self.tblMediaCards.reloadData()
}
}
但它仍然因同样的原因崩溃。尽管委托工作正常。
目标错误:
cell.btnDelete.addTarget(self, action: #selector(AddNewVC.deleteItem(sender:)), for: .touchUpInside)
方法 AddNewVC.deleteItem(sender:)
不是 self
的一部分,而是另一个 class 成员的一部分。尝试:
cell.btnDelete.addTarget(self.viewController, action: #selector(AddNewVC.deleteItem(sender:)), for: .touchUpInside)
为了安全起见,我宁愿在同一个 viewcontroller 中有一个目标方法,然后让这个调用 datasource/subviewcontroller 方法。
我有一个单独的 class 用于 UITableViewDataSource
我的 UITableView
import UIKit
class CardDataSource: NSObject, UITableViewDataSource {
//MARK:- Property
var medialObjects: [MediaCardObject]?
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
var viewController: AddNewVC?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return medialObjects?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let obj = medialObjects![indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "MediaTextTableViewCell") as! MediaTextTableViewCell
cell.btnDelete.tag = indexPath.row
cell.btnDelete.addTarget(self, action: #selector(AddNewVC.deleteItem(sender:)), for: .touchUpInside)
cell.tfCardText.text = obj.path
cell.tfCardText.tag = indexPath.row
cell.tfCardText.returnKeyType = .done
cell.tfCardText.delegate = viewController
cell.selectionStyle = .none
return cell
}
}
数据在我的 UITableView
上加载正常,但问题是当我点击删除按钮时它崩溃并显示
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MediaCards.CardDataSource deleteItemWithSender:]: unrecognized selector sent to instance 0x600003394cc0'
我也试过了
cell.btnDelete.addTarget(self, action: #selector(viewController?.deleteItem(sender:)), for: .touchUpInside)
这里是AddNewVC
//MARK:- Delete
@objc func deleteItem(sender: UIButton) {
let selectedIndex = sender.tag
deleteObjectIndexPath = IndexPath(row: selectedIndex, section: 0)
confirmDelete()
}
并在 AddNewVC
class
var tblDataSource = CardDataSource()
override func viewDidLoad() {
super.viewDidLoad()
tblDataSource.viewController = self
tblMediaCards.dataSource = tblDataSource
if forEdit {
let cards = mediaObject?.cards?.allObjects as! [MediaCard]
for obj in cards {
let mediaCardObj = MediaCardObject.init(type: obj.type ?? "", path: obj.path ?? "", index: Int(obj.index))
self.medialObjects.append(mediaCardObj)
}
medialObjects = medialObjects.sorted(by: { [=14=].index! < .index! })
tblDataSource.medialObjects = medialObjects
self.tblMediaCards.reloadData()
}
}
但它仍然因同样的原因崩溃。尽管委托工作正常。
目标错误:
cell.btnDelete.addTarget(self, action: #selector(AddNewVC.deleteItem(sender:)), for: .touchUpInside)
方法 AddNewVC.deleteItem(sender:)
不是 self
的一部分,而是另一个 class 成员的一部分。尝试:
cell.btnDelete.addTarget(self.viewController, action: #selector(AddNewVC.deleteItem(sender:)), for: .touchUpInside)
为了安全起见,我宁愿在同一个 viewcontroller 中有一个目标方法,然后让这个调用 datasource/subviewcontroller 方法。