什么是UICollection的IndexPath

时间:2018-01-30 16:33:02

标签: ios arrays swift uicollectionview

我在使用UICollectionViews时遇到了两个问题,我在某些情况下都认为它与IndexPath相关,但是我不知道什么时候调用了Indexpath或它究竟是什么当它被更新或更改时 无论如何,这是我的问题: 1.不知何故,Indexpath多次为0?Youtube VIDEO showing behavior

这个特定行为的

是代码:

extension PointAllocVC: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return (playerArray?.count)!
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "playerCell", for: indexPath) as! PointAllocCell
        cell.cellDelegate = self
        cell.cellIndex = indexPath.row
        cell.nameLabel.text = playerArray![indexPath.row].alias
        cell.scoreLabel.text = String(currentScore[indexPath.row])
        cell.minusBtn.layer.cornerRadius = 15
        cell.plusBtn.layer.cornerRadius = 15
        cell.ptsRemaining = pointsToAllocate
        cell.ptsUsed = abs(pointsUsedInCells[indexPath.row])
        if indexPath.row == 0 {
            cell.isSelf = true
            cell.layer.borderWidth = 5
            cell.layer.borderColor = UIColor.blue.cgColor
        } else {
            cell.isSelf = false
        }
        cell.updatedButtons()
        return cell
    }

正如你所看到的那样,只有在INDEXPATH.ROW == 0时,单元格才有边框(因为那是当前用户)。但是当我点击按钮(见下面的按钮逻辑)突然他们所有的索引路径== 0?

class PointAllocCell: UICollectionViewCell {
    var isSelf: Bool = false
    var cellIndex: Int?
    var ptsRemaining: Int = 0
    var ptsUsed: Int = 0
    var cellDelegate: PointsAllocDelegate?

    @IBAction func plusTapped(_ sender: Any) {
        if cellDelegate != nil {
            cellDelegate!.plusTapReported(fromCell: cellIndex!)
        }
        updatedButtons()
    }

    @IBAction func minusTapped(_ sender: Any) {
        if cellDelegate != nil {
            cellDelegate!.minusTapReported(fromCell: cellIndex!)
        }
        updatedButtons()
    }

    func updatedButtons() {
        switch (ptsRemaining, ptsUsed) {
        case (0,0):
            plusBtn.isEnabled = false
            minusBtn.isEnabled = false
        case (0,_):
            if isSelf{
                plusBtn.isEnabled = false
                minusBtn.isEnabled = true
            } else {
                plusBtn.isEnabled = true
                minusBtn.isEnabled = false
            }
        case (_,0):
            if isSelf{
                plusBtn.isEnabled = true
                minusBtn.isEnabled = false
            } else {
                plusBtn.isEnabled = false
                minusBtn.isEnabled = true
            }
        default:
            plusBtn.isEnabled = true
            minusBtn.isEnabled = true
        }
        pointLabel.text = String(ptsUsed)
    }
}

最后代表:

extension PointAllocVC: PointsAllocDelegate {
    func plusTapReported(fromCell: Int) {
        if fromCell == 0 {
            //this is self
            pointsToAllocate -= 1
            pointsUsedInCells[fromCell] += 1
        } else {
            pointsToAllocate += 1
            pointsUsedInCells[fromCell] += 1
        }
        reloadCollection()
        reloadLabels()
    }

    func minusTapReported(fromCell: Int) {
        if fromCell == 0 {
            //this is self
            pointsToAllocate += 1
            pointsUsedInCells[fromCell] -= 1
        } else {
            pointsToAllocate -= 1
            pointsUsedInCells[fromCell] -= 1
        }
        reloadCollection()
        reloadLabels()
    }
}

现在。第二个问题,我在做以下事情时得到它

playerArray.remove(at: gKPlayerArray.index(of: playerDed)!)

这行代码没有做任何事情,但是当我调用" reloadData"我得知IndexPath.row超出范围(出于某种原因,它仍然认为playerArray的大小为X + 1,即使我在调用之前删除了一个项目。

2 个答案:

答案 0 :(得分:1)

单元格永远不需要知道自己的indexPath。这是一个非常糟糕的设计。

重构代码,这样就不会将行或indexPath传递给单元格。

更改您的单元格委托协议以传递实际单元格,而不是Int

实际上实现委托方法的类现在将被告知代表哪个单元调用委托方法,如果需要,该类可以确定单元的indexPath。

您还需要更新cellForItemAt

此代码存在问题:

    if indexPath.row == 0 {
        cell.isSelf = true
        cell.layer.borderWidth = 5
        cell.layer.borderColor = UIColor.blue.cgColor
    } else {
        cell.isSelf = false
    }

无论何时设置属性,都必须始终将其重置为其他条件。

    if indexPath.row == 0 {
        cell.isSelf = true
        cell.layer.borderWidth = 5
        cell.layer.borderColor = UIColor.blue.cgColor
    } else {
        cell.isSelf = false
        cell.layer.borderWidth = 0
    }

您不需要重置0宽边框的颜色。

答案 1 :(得分:0)

@rmaddy在回答中没有提到一件事 - 因为您使用UICollectionView,所以不应该使用row的{​​{1}}属性,而应使用{{1属性。鉴于集合视图的性质及其在布局单元格方面的灵活性,系统无法识别“行”。使用IndexPath时,应使用item属性。

  

var row:Int   标识表视图的一部分中的行的索引号    var item:Int   标识集合视图的某个部分中的项目的索引号。

https://developer.apple.com/documentation/foundation/nsindexpath