当SearchController处于活动状态时,CollectionView自定义单元格无法正确更新

时间:2020-03-11 20:19:27

标签: swift iphone uitableview uicollectionview uisearchbar

我有一个带有searchcontroller和自定义单元格的collectionview。当我在搜索未激活时在单元格中进行编辑时,所有内容都会毫无问题地得到更新。但是当searchcontroller处于活动状态时,我的编辑不能正确地重新加载。这是我的一些代码。

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //SEARCH
    if searchController.isActive{
        return searchResults.count
    }else{
    return products.count
    }
    //SEARCH
}

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

    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.ProductCell, for: indexPath) as? ProductCell {

        //SEARCH
        // Determine if we get the products from search result or the original array
        let searchItem = (searchController.isActive) ? searchResults[indexPath.item] : products[indexPath.item]

        cell.product = searchItem
        cell.delegate = self

        return cell
    }
    return UICollectionViewCell()
}

我有一个侦听器,用于在集合的单元格中填充信息,这是我的侦听器代码:

func setProductsListener(){

    listener = ProductsService.getProducts { [weak self] change, product in

        guard let self = self else { return }
        switch change.type {
        case .added:
            self.onDocumentAdded(change: change, product: product)
        case .modified:
            self.onDocumentModified(change: change, product: product)
        case .removed:
            self.onDocumentRemoved(change: change)

        @unknown default: break
        }
    }
}

这是我的更改重新加载到collectionView的位置:

    func onDocumentAdded(change: ProductChange, product: Product){
        let newIndex = Int(change.newIndex)
        products.insert(product, at: newIndex)
        collectionView.insertItems(at: [IndexPath(item: newIndex, section: 0)])

        // calculate and set title for cart subtotal
        cartBtn.setTitle(subtotal.penniesToFormattedCurrency(), for: .normal)
        cartBtn.sizeToFit()
    }

    func onDocumentModified(change: ProductChange, product: Product) {

        if change.newIndex == change.oldIndex {

            // Item changed, but remained in the same position
            let index = Int(change.newIndex)
            products[index] = product

            (collectionView.cellForItem(at: IndexPath(item: index, section: 0)) as? ProductCell)?.product = product

            // calculate and set title for cart subtotal
            cartBtn.setTitle(subtotal.penniesToFormattedCurrency(), for: .normal)
            cartBtn.sizeToFit()
        } else {

            // Item changed and changed position
            let oldIndex = Int(change.oldIndex)
            let newIndex = Int(change.newIndex)
            products.remove(at: oldIndex)
            products.insert(product, at: newIndex)

            collectionView.moveItem(at: IndexPath(item: oldIndex, section: 0), to: IndexPath(item: newIndex, section: 0))

            // calculate and set title for cart subtotal
            cartBtn.setTitle(subtotal.penniesToFormattedCurrency(), for: .normal)
            cartBtn.sizeToFit()
        }
    }

    func onDocumentRemoved(change: ProductChange){
        let oldIndex = Int(change.oldIndex)
        products.remove(at: Int(oldIndex))
        collectionView.deleteItems(at: [IndexPath(item: oldIndex, section: 0)])

        // calculate and set title for cart subtotal
        cartBtn.setTitle(subtotal.penniesToFormattedCurrency(), for: .normal)
        cartBtn.sizeToFit()
    }

这是当搜索控制器未激活时我的UI的外观:

enter image description here

当我开始搜索并输入单词“ As ..”(试图搜索芦笋)时,我得到以下结果:

enter image description here

到目前为止,我没有问题。但是,当我尝试在搜索控制器处于活动状态时单击“加号”或“减号”以更改数量时;错误的索引也会被更新;看下面的截图。不仅索引0会针对芦笋进行更新;索引2也将更新为同一项目芦笋。

enter image description here

我很确定问题出在下面的代码中,一旦修改完成;当搜索控制器处于活动状态时,错误的索引也会更新。知道如何更改下面的代码,以便在搜索控制器处于活动状态时更新正确的索引吗?

func onDocumentModified(change: ProductChange, product: Product) {

    if change.newIndex == change.oldIndex {

        // Item changed, but remained in the same position
        let index = Int(change.newIndex)
        products[index] = product

        (collectionView.cellForItem(at: IndexPath(item: index, section: 0)) as? ProductCell)?.product = product

        // calculate and set title for cart subtotal
        cartBtn.setTitle(subtotal.penniesToFormattedCurrency(), for: .normal)
        cartBtn.sizeToFit()
    }

1 个答案:

答案 0 :(得分:0)

我通过将以下内容添加到func onDocumentModified中来解决了这个问题:

        if searchController.isActive {

            for item in searchResults {

                if item.id == product.id {
                    let searchedItemIndex = Int((searchResults.firstIndex(of: item))!)

                    (collectionView.cellForItem(at: IndexPath(item: searchedItemIndex, section: 0)) as? ProductCell)?.product = product
                }
            }

        } else {

            collectionView.reloadItems(at: [IndexPath(item: index, section: 0)])                
        }