我在使用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,即使我在调用之前删除了一个项目。
答案 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