开发者社区> 问答> 正文

为多个呼叫swift 5更新集合视图数据源的正确方法

我有一个集合视图,我在每个呼叫中加载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()
        }
    })
}

而且它运行得很完美。

现在,我添加了一个顶部菜单部分,有几个选项。 https://i.stack.imgur.com/bMAIr.png 如果用户点击该部分,则函数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并在物理设备上崩溃时,对Xcode发出警告。我对此做了一些研究,并提出了使用的解决方案。performBatchUpdates但他们都不起作用。因此,我的问题是,在这种情况下,在收集视图中获取数据和加载数据的最佳方法是什么?提前谢谢。

展开
收起
游客5akardh5cojhg 2019-12-09 00:17:10 706 0
0 条回答
写回答
取消 提交回答
问答分类:
问答地址:
问答排行榜
最热
最新

相关课程

更多

相关电子书

更多
OpenStack Swift 海量小文件优化之路 立即下载
From Java/Android to Swift iOS 立即下载
Swift在Airbnb的应用实践 立即下载