单元格的委托在 didSelectItemAt 中为 nil

Cell's delegate is nil in didSelectItemAt

我有一个 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

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}

当您在 cellForItemAt 之外使用 dequeueReusableCell 时,它将 return 一个与单击的单元格不同的单元格