ios - Cell's delegate is nil in didSelectItemAt
问题描述
I have a UICollectionViewCell
with an item Desk
. Desk has a Bool
property that I want to change when a cell is tapped.
I'm trying to better familiarize myself with the delegate pattern, and want to avoid using something like a transparent button overlaid on the cell. I thought it would work to assign the cell's delegate in cellForItemAt
and trigger the delegate method in didSelectItemAt
, but the cell's delegate is nil when I check in didSelectItemAt
.
Struct:
struct Desk: Equatable, Codable {
var name: String
var wasTouched: Bool = false
}
Protocol:
protocol TouchTheDesk: AnyObject {
func youTouchedIt(cell: DeskCell)
}
Cell:
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
}
}
Conform VC to Protocol and define delegate method:
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)
}
edit: If I call the delegate method directly in didSelectItemAt
and pass in the cell, the indexPath for the cell is nil in the delegate method
解决方案
内部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
,将返回与单击的单元格不同的单元格
推荐阅读
- time-complexity - 我是否过度简化了计算复杂性
- ruby-on-rails - 在 Rails API 中处理状态 429
- javascript - 网页是否可以检测到它是从 webview 应用程序访问的?
- sql - oracle sql如何选择第一行和最后一行两个选择
- arrays - Swift - json嵌套数组不返回值
- ruby-on-rails - 在部署 rails 应用程序时让 AWS S3 与 heroku 一起使用
- python - 每个 jupyter notebook 是否使用线程或进程
- javascript - 多次调用 sagaMiddleware.run 是否安全?
- r - 使用 R 将 OSX 中的 .db 日期转换为可读日期
- python - 如何将 sys.argv 连接到我的浮点值?