Swift-如何在具有多个部分的collectionView上执行批更新

时间:2019-07-12 12:55:52

标签: ios swift uicollectionview

我有一个collectionView,该视图具有3个部分,每个部分具有一个不同的单元格(将单元格的数据分为单独的部分比仅1个部分更容易)。

collectionView的数据源中只有一个dataModel,它会更新,但是我只需要该更新就可以在第一部分中显示(会添加一个新标签)。当我尝试运行function getWordByPosition(str, pos) { let leftSideString = str.substr(0, pos); let rightSideString = str.substr(pos); let leftMatch = leftSideString.match(/[^.,\s]*$/); let rightMatch = rightSideString.match(/^[^.,\s]*/); let resultStr = ''; if (leftMatch) { resultStr += leftMatch[0]; } if (rightMatch) { resultStr += rightMatch[0]; } return { index: leftMatch.index, word: resultStr }; } 时,整个布局变得混乱,它从显示所有3个部分变为仅显示最后一个部分,而前2个部分完全消失了。这不是约束,因为当我弹出并向后推时,布局很完美,新标签在第一部分显示了更新的数据,而其他两个则很好。我运行执行批处理更新时似乎出现了问题

我尝试过:

collectionView.performBatchUpdates

我尝试过:

let updatedDataModel = ...

guard let indexOfItem = tableData.firstIndex(where: { $0.itemId == updatedDataModel.itemId }) else { return }

tableData[indexOfItem] = updatedDataModel

let indexPath = IndexPath(item: indexOfItem, section: 0)

UIView.animate(withDuration: 0) {

    self.collectionView.performBatchUpdates({ [weak self] in

        self?.collectionView.reloadItems(at: [indexPath])
        self?.collectionView.layoutIfNeeded()

    }) { (_) in
        print("success")
    }
}

我尝试过:

collectionView.performBatchUpdates({
    let indexSet = IndexSet(integer: 0)
    self.collectionView.reloadSections(indexSet)
}, completion: nil)

cellForItem:

let updatedDataModel = ...

guard let indexOfItem = tableData.firstIndex(where: { $0.itemId == updatedDataModel.itemId }) else { return }

tableData[indexOfItem] = updatedDataModel

let indexPath0 = IndexPath(item: indexOfItem, section: 0)
let indexPath1 = IndexPath(item: indexOfItem, section: 1)
let indexPath2 = IndexPath(item: indexOfItem, section: 2)

UIView.animate(withDuration: 0) {

    self.collectionView.performBatchUpdates({ [weak self] in

        self?.collectionView.reloadItems(at: [indexPath0, indexPath1, indexPath2])
        self?.collectionView.layoutIfNeeded()

    }) { (_) in
        print("success")
    }
}

数据源:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // *** this section is where the updated data (an additional label) needs to appear
    if indexPath.section == 0 {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: topCell, for: indexPath) as! TopCell
        cell.dataModel = tableData[indexPath.item]
        return cell
    }

    if indexPath.section == 1 {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: middleCell, for: indexPath) as! MiddleCell
        cell.dataModel = tableData[indexPath.item]
        return cell
    }

    if indexPath.section == 2 {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: bottomCell, for: indexPath) as! BottomCell
        cell.dataModel = tableData[indexPath.item]
        return cell
    }

    // if for some reason something goes wrong above but this NEVER runs
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: errorCell, for: indexPath) as! ErrorCell
    return errorCell
}

我要去哪里错了?

1 个答案:

答案 0 :(得分:0)

请勿使用collectionView.performBatchUpdates,而只需编写以下内容以仅在所需部分中重新加载数据:

let indexSet = IndexSet(integer: 0)       // Change integer to whatever section you want to reload
collectionView.reloadSections(indexSet)

如果您不希望为此UICollectionView重新加载使用任何动画,请使用:

UIView.performWithoutAnimation {
    // same code as above
}


祝你好运。