我有一个集合视图,并且每次调用(Fetching)从其中的 firebase 加载 20 个单元格。所以我有两个部分,第一部分是我的源数组的计数,第二部分只是在bool
值为fetch more
真时显示加载单元。
这是集合视图代码:
extension ProductViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return self.objectArray.count
} else if section == 1 {
return fetchingMore ? 1 : 0
}
return 0
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.size.height
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
var minimumLineSpacingForSectionAt: CGFloat
if section == 0 {
minimumLineSpacingForSectionAt = -50
} else {
minimumLineSpacingForSectionAt = 0
}
return minimumLineSpacingForSectionAt
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.section == 0 {
return CGSize(width: productCollectionView.bounds.width, height: CommonService.heightForRowAtIndexPathForiPhones(cellType: .itemCell))
} else {
return CGSize(width: productCollectionView.bounds.width, height: 70)
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.section == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ItemAlbumCollectionViewCell", for: indexPath) as! ItemAlbumCollectionViewCell
cell.setUpCell(product: objectArray[indexPath.row]!)
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LoadingCollectionViewCell", for: indexPath) as! LoadingCollectionViewCell
cell.activityIndicator.startAnimating()
return cell
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let productCategoryViewController = Storyboards.ProductCategoryVC.controller as! ProductCategoryViewController
productCategoryViewController.products = objectArray[indexPath.row]!
pushViewController(T: productCategoryViewController)
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
guard let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "StreachyCollectionHeaderReusableView", for: indexPath) as? StreachyCollectionHeaderReusableView else { fatalError("Invalid view type") }
return headerView
default:
assert(false, "Invalid element type")
}
}
}
这是为获取数据而调用的函数:
func pagination(forDivisionCollection: String) {
fetchProduct(forDivisionCollection: forDivisionCollection, completion: { newData in
self.productCollectionView.reloadSections(IndexSet(integer: 1))
self.objectArray.append(contentsOf: newData)
self.endReached = newData.count == 0
self.fetchingMore = false
UIView.performWithoutAnimation {
self.productCollectionView.reloadData()
}
})
}
它运行良好。
现在我添加了一个带有几个选项的顶部菜单部分。
如果用户点击该部分,func pagination(forDivisionCollection: String)
则将使用参数调用该函数,它将使用该参数过滤数据源并根据顶部菜单选项填充数据源,如下所示:
func pagination(isForNewDivision: Bool, forDivisionCollection: String) {
self.fetchingMore = true
if isForNewDivision == true {
self.objectArray.removeAll()
}
fetchProduct(forDivisionCollection: forDivisionCollection, completion: { newData in
self.productCollectionView.reloadSections(IndexSet(integer: 1))
self.objectArray.append(contentsOf: newData)
self.endReached = newData.count == 0
self.fetchingMore = false
UIView.performWithoutAnimation {
self.productCollectionView.reloadData()
}
})
}
但是我'Invalid update: invalid number of items in section 0.
在模拟器中运行 Xcode 时收到警告,并且它在物理设备上崩溃了。我进行了一些研究并提出了使用的解决方案,performBatchUpdates
但它们都不起作用。所以我的问题是在这种情况下,获取数据并在集合视图中加载的完美方式是什么?提前非常感谢。