我有一个UICollectionViewCell
和一个项目Desk
。 Desk具有一个Bool
属性,我想在点击一个单元格时对其进行更改。
我试图更好地熟悉委托模式,并希望避免使用覆盖在单元格上的透明按钮之类的东西。我认为在cellForItemAt
中分配单元格的委托并在didSelectItemAt
中触发委托方法是可行的,但是当我签入didSelectItemAt
时,单元格的委托为nil。
结构:
struct Desk: Equatable, Codable {
var name: String
var wasTouched: Bool = false
}
协议:
protocol TouchTheDesk: AnyObject {
func youTouchedIt(cell: DeskCell)
}
单元格:
import UIKit
class DeskCell: UICollectionViewCell {
@IBOutlet weak var deskLbl: UILabel!
weak var delegate: TouchTheDesk?
var desk: Desk? {
didSet {
updateViews()
}
}
func updateViews() {
self.deskLbl.text = desk?.name
}
}
使VC符合协议并定义委托方法:
extension NotAShoppingListVC: TouchTheDesk {
func youTouchedIt(cell: DeskCell) {
if cell.desk?.wasTouched != nil {
cell.desk!.wasTouched = !cell.desk!.wasTouched
} else {
cell.desk!.wasTouched = true
}
collectionView.reloadData()
}
}
cellForItemAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? DeskCell else {return UICollectionViewCell()}
cell.desk = deskDealer.desks[indexPath.item]
if cell.desk!.wasTouched { //assigned on line above
cell.backgroundColor = .red
} else {
cell.backgroundColor = .green
}
cell.delegate = self
return cell
}
didSelectItemAt:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? DeskCell else {return}
#warning("delegate is nil")
cell.delegate?.youTouchedIt(cell: cell)
}
编辑:如果我直接在didSelectItemAt
中调用委托方法并传递单元格,则该单元格的indexPath在委托方法中为nil
答案 0 :(得分:2)
内部didSelectItemAt
替换
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? DeskCell else {return}
使用
guard let cell = collectionView.cellForItem(at: indexPath) as? DeskCell else {return}
当您在dequeueReusableCell
之外使用cellForItemAt
时,它将返回除单击的单元格以外的其他单元格