我有一个自定义tableviewHeaderFooterView
,在其中我为自定义tableViewCell
类中的按钮设置了一个目标事件(checkButton
是按钮,并且当用户点击它。)
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let userModel = Data.userModels[section]
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId") as! SectionHeader
cell.setup(model: userModel)
cell.checkButton.tag = section
cell.checkButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
return cell.contentView
}
在该函数中,我想根据用户是否点击单元格来创建或删除数组中的项(即,如果他们点击按钮,然后向数组中添加某些内容,但是如果他们点击了该单元格再按一次,然后从数组中删除该对象。)
@objc func handleTap(sender: UIButton) {
sender.isSelected = !sender.isSelected
if sender.isSelected == true {
let model = ItemModel(itemName: item, price: price)
ItemModelFunctions.createItem(for: sender.tag, using: model)
}
if sender.isSelected == false {
ItemModelFunctions.removeFromUser(from: sender.tag)
}
print(sender.tag)
}
以下是createItem
和removeFromUser
函数:
struct ItemModelFunctions {
static func createItem(for userIndex: Int, using itemModel: ItemModel) {
Data.userModels[userIndex].itemModels.append(itemModel)
}
static func removeFromUser(from userIndex: Int) {
Data.itemModels.remove(at: userIndex)
}
}
当我两次点击按钮以将其从阵列中删除时,我收到一条错误消息,提示Data.itemModels.remove(at: userIndex)
超出范围。
我知道在tableViewHeaderFooterView
中使用原型单元并不是完全正确的方法,但是我已经看到其他程序员和YouTuber成功地做到了这一点。我的问题是否来自使用原型电池?还是我以错误的方式从数组中删除了该项?谢谢大家的帮助!
答案 0 :(得分:1)
每次重用节标题时,都会运行checkButton.addTarget函数。 然后,当重复使用多次时,它将为单元复制事件。 我认为您不应该使用此解决方案。相反,我认为您应该编写委托方式来解决您的问题。 例如:
protocol SectionHeaderDelegate: class {
func checkButtonDidTap(section: SectionHeader)
}
class SectionHeader: UITableViewCell {
weak var delegate: SectionHeaderDelegate
@IBOutlet weak var checkButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
checkButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
}
func handleTap() {
self.delegate.checkButtonDidTap(section: self)
}
}
,然后在viewForHeaderInSection
函数中设置cell.delegate = self。并实现协议SectionHeaderDelegate。
答案 1 :(得分:1)
Thanh Vu的解决方案有效。另一个解决方案是将IBAction添加到您的ViewController:
@IBAction func buttonTapped(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
let cell = sender.superview?.superview as! SectionHeader
if let indexPath = mainTableView.indexPath(for: cell) {
// if sender.isSelected etc...
}
}
答案 2 :(得分:1)
// Please maintain one more array i.e selectedIndexArray and follow below code.
var selectedIndexArray = [Integer]()
@IBAction func buttonTapped(_ sender: UIButton) {
let button = sender
if selectedIndexArray.contains(button.tag) {
button.tag --> Remove this tag from selectedIndexArray
let model = ItemModel(itemName: item, price: price)
ItemModelFunctions.createItem(for: sender.tag, using: model)
} else
{
selectedIndexArray.append(button.tag)
ItemModelFunctions.removeFromUser(from: sender.tag)
}
//reload tableview.
self.tableView.reloadData()
}