单元格的委托在didSelectItemAt中为nil

时间:2019-12-21 14:00:30

标签: ios swift uicollectionview delegates uicollectionviewcell

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

1 个答案:

答案 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时,它将返回除单击的单元格以外的其他单元格