UICollectionViewCell дублирование - PullRequest
       19

UICollectionViewCell дублирование

0 голосов
/ 11 сентября 2018

Я знаю, что здесь уже задавали этот вопрос, но моя проблема немного отличается, и следование этому руководству не помогло:

Повторяющаяся ячейка CollectionView при загрузке дополнительных данных

Итак, моя ситуация такова:

  1. Я нахожусь на ProductPageView - удаление продукта
  2. Продукт удален из базы данных (успешно)
  3. Размотка Segue запускается
  4. При обратном вызове я удаляю удаленный продукт из коллекции
  5. Обновляю коллекцию
  6. Просмотр загружается с дубликатом ячейки

Началоmy cellForItemAtIndexPath:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "product_collection_cell", for: indexPath) as! ProductsCollectionViewCell
    cell.ProductImageView.image = nil
    cell.ProductName.text = nil
    cell.ProductPrice.text = nil
    cell.productUniqueID = nil

    let prodInCell =  searchActive ? filtered[indexPath.row] : products[indexPath.row]

    let prodID = prodInCell.getUniqueID()
    let dbRef = Storage.storage().reference().child(prodID).child("pic0.jpg")
    cell.contentMode = .scaleAspectFit
    cell.ProductImageView.image = #imageLiteral(resourceName: "DefaultProductImage")
    dbRef.downloadURL(completion:
        {
            url, error in
            if let error = error
            {
                print (error)
            }
            else if let url = url
            {
                cell.ProductImageView.loadImageUsingUrlString(urlString: url.absoluteString)
                cell.ProductImageView.contentMode = UIViewContentMode.scaleToFill
                cell.layoutIfNeeded()
            }
    })
    cell.ProductImageView.clipsToBounds = true

    //cell.ProductName = UILabel()
    cell.ProductName.text = prodInCell.getName()

    //cell.ProductPrice = UILabel()
    cell.ProductPrice.text = String(prodInCell.getPrice())
    cell.productUniqueID = prodInCell.getUniqueID()
    return cell
}

Моя функция обратного вызова для отката:

@IBAction func unwindFromDeleteSegue(segue: UIStoryboardSegue)
{
    if (prodToLoad == nil) {return}

    for product in products
    {
        if product.getUniqueID() == prodToLoad?.getUniqueID()
        {
            products.remove(at: products.index(of: product)!)
            ProductsCollection.reloadData()
            break
        }
    }
}

My numberOfItemsInSection:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        if searchActive
        {
            return filtered.count
        }
        else
        {
            return products.count    //return number of rows in section
        }
    }

Может кто-нибудь, пожалуйста, укажите мнегде источник моей ошибки может быть?

Примечание:

Это не происходит только при загрузке большего количества данных, это также происходит, когда есть только 1элемент в коллекции, и ячейки не используются повторно

РЕДАКТИРОВАТЬ:

Я заметил, что когда эта строка находится вкомментарий:

StaticFunctions.ProductsStaticFunctions.removeProductFromDatabase(productUniqueID: self.productToDisplay.getUniqueID(), ownerID: self.productToDisplay.getOwnerID())

Работает нормально.Когда я отменяю комментарий, он снова перестает работать правильно.

public static func removeProductFromDatabase(productUniqueID: String, ownerID: String)
        {

        let childUpdates = ["/\(Constants.TREE_A)/\(ownerID)/\(productUniqueID)/" : nil,
                            "/\(Constants.TREE_B)/\(ownerID)/\(productUniqueID)/" : nil,
                            "/\(Constants.TREE_C)/\(productUniqueID)/" : nil,
                            "/\(Constants.TREE_D)/\(productUniqueID)/" : nil,
                            "/\(Constants.TREE_E)/\(ownerID)/\(productUniqueID)/": nil,
                            "/\(Constants.TREE_F)/\(ownerID)/\(productUniqueID)/": nil,
                            "/\(Constants.TREE_G)/\(productUniqueID)/" : nil,
                            "/\(Constants.TREE_H/\(productUniqueID)/" : nil
            ] as [String : Any?]

        Constants.refs.databaseRoot.updateChildValues(childUpdates)
    }

Мой метод добавления товара в массив:

ref?.observe(.value, with:
            { (snapshot) in

            let allChildrenObjects = snapshot.children.allObjects
            if allChildrenObjects.count == 0 {self.StopLoadingAnimation() ; return}

            for child in allChildrenObjects as! [DataSnapshot]
            {
                // Code to execute when new product is added
                let prodValueDictionary = child.value as? NSDictionary

                if ((currentUserId == prodValueDictionary?[Constants.Products.ProductFields.PRODUCT_OWNER_ID] as? String) == itemsOfCurrentUser)
                {
                    self.AddProductToCollection(productAsDictionary: prodValueDictionary, IsProductMine: itemsOfCurrentUser)
                    self.DispatchQueueFunc()
                }
            }

1 Ответ

0 голосов
/ 13 сентября 2018

Так как вы используете

ref?.observe(.value, with:
        { (snapshot) in

вы будете находиться под угрозой, что этот обратный вызов вызывается при каждом редактировании, которое происходит с ним, что приводит к неожиданным результатам, когда вы сталкиваетесь с дублированием данных внутри массива, поэтому вам нужно одно наблюдение

ref?.observeSingleEvent(.value, with:
        { (snapshot) in
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...