我有一个带有项目UICollectionViewCell
的Desk
。 Desk有一个Bool
属性,我想在点击一个单元格时更改它。
我正在尝试更好地熟悉委托模式,并希望避免使用覆盖在单元格上的透明按钮之类的东西。我以为在cellForItemAt
中分配单元格的委托并在didSelectItemAt
中触发委托方法是可行的,但是当我签入didSelectItemAt
时,单元格的委托为nil。
Struct:
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
内部didSelectItemAt
替换
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? DeskCell else {return}
with
guard let cell = collectionView.cellForItem(at: indexPath) as? DeskCell else {return}
[当您在dequeueReusableCell
之外使用cellForItemAt
时,它将返回与单击的单元格不同的其他单元格