在 didSelectItemAt 中,单元格的代表为零

Posted

技术标签:

【中文标题】在 didSelectItemAt 中,单元格的代表为零【英文标题】:Cell's delegate is nil in didSelectItemAt 【发布时间】:2019-12-21 14:00:30 【问题描述】:

我有一个 UICollectionViewCell 和一个项目 Desk。 Desk 有一个 Bool 属性,我想在点击单元格时更改它。

我正在尝试更好地熟悉委托模式,并希望避免使用覆盖在单元格上的透明按钮之类的东西。我认为在cellForItemAt 中分配单元格的委托并在didSelectItemAt 中触发委托方法会起作用,但是当我签入didSelectItemAt 时,单元格的委托为零。

结构:

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符合Protocol并定义委托方法:

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

【问题讨论】:

你不能在cellForItemAt之外打电话给dequeueReusableCell 你是说你在 didSelectItemAt 方法中得到 indexPath nil 吗? 【参考方案1】:

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 时,它会返回一个与点击的单元格不同的单元格

【讨论】:

谢谢,我显然需要阅读可重用视图,而不是委托模式,哈哈

以上是关于在 didSelectItemAt 中,单元格的代表为零的主要内容,如果未能解决你的问题,请参考以下文章

获取自定义单元格的标识符

覆盖单元格中的触摸后,Swift CollectionView didSelectItemAt 不再工作

UICollectionView 的 didSelectItemAt 仅在双击时调用

UIColctionView didSelectItemAt 问题

UICollectionView didSelectItemAt() 并根据状态添加/删除视图

CollectionView 中的 CollectionView:使用 didSelectItemAt 执行Segue