Cell的委托在didSelectItemAt中为零

问题描述 投票:0回答:1

我有一个带有项目UICollectionViewCellDesk。 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

ios swift uicollectionview delegates uicollectionviewcell
1个回答
2
投票

内部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时,它将返回与单击的单元格不同的其他单元格

© www.soinside.com 2019 - 2024. All rights reserved.