Представление коллекции не перезагружается после получения данных - PullRequest
0 голосов
/ 25 августа 2018

Ситуация: я получаю данные из Firebase. После извлечения данных я хочу обновить / перезагрузить таблицу collectionView.

Проблема: collectionView не обновляется. Вот коды с небольшим объяснением.

var allProducts = [Product]()

override func viewDidLoad() {
    super.viewDidLoad()

    mostPopularCollectionView.dataSource = self
    mostPopularCollectionView.delegate = self

    getAllProducts { (returnedProductArray) in
        self.allProducts = returnedProductArray
        self.mostPopularCollectionView.reloadData()
    }

}
  1. Функция getAllProducts работает отлично. Если я распечатываю allProducts.count в закрытии, я получаю правильный номер (3).
  2. Если я распечатаю allProducts.count за пределами закрытия, мой счет равен нулю.
  3. Я пытался поместить функцию getAllProducts в viewWillAppear, но это не решило проблему

    расширение FeedTableViewController: UICollectionViewDataSource, UICollectionViewDelegate {

        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    
        return 3
    
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mostPopularCell", for: indexPath) as? MostPopularCollectionViewCell else {return UICollectionViewCell()}
    
    
        if allProducts.count > 0 {
            let product : Product = allProducts[indexPath.row]
            if let productImageUrl = product.imageUrlArray.first {
                cell.upadateCellUI(forProductName: product.title, forProductImage: productImageUrl, forProductPrice: product.price)
            }
            return cell
        } else {
            return cell
        }
    
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let productVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "productVC") as! ProductViewController
        productVC.product = allProducts[indexPath.row]
        present(productVC, animated: true, completion: nil)
    }
    

    }

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

Таким образом, единственная проблема заключается в том, как мне заставить collectionView перезагружаться после получения данных из Firebase? Любая помощь очень ценится

Это функция getAllProducts, используемая для извлечения всех данных из Firebase.

//MARK:- Retrieve all products from Firebase
func getAllProducts (handler: @escaping (_ allProducts: [Product]) -> ()) {

    //TODO:- Create an empty array to store all product fetched from Firebase
    var productArray = [Product]()
    var imageUrlArray = [String]()

    //TODO:- Create reference to Firebase database
    let DB = Database.database().reference()

    //TODO:- Create reference to products
    let REF_PRODUCTS = DB.child("Product")

    //TODO:- Snapshot of all products in database
    REF_PRODUCTS.observeSingleEvent(of: .value) { (allProductsSnapshot) in
        guard let allProductsSnapshot = allProductsSnapshot.children.allObjects as? [DataSnapshot] else {return}

        for product in allProductsSnapshot {
            let title = product.childSnapshot(forPath: "name").value as! String
            let price = product.childSnapshot(forPath: "price").value as! String
            let id = product.childSnapshot(forPath: "id").value as! Int
            let viewCount = product.childSnapshot(forPath: "viewCount").value as! Int
            let description = product.childSnapshot(forPath: "description").value as! String

            let REF_IMAGEURL = REF_PRODUCTS.child(String(id)).child("image")

            REF_IMAGEURL.observeSingleEvent(of: .value, with: { (allImageUrlSnapshot) in
                guard let allImageUrlSnapshot = allImageUrlSnapshot.children.allObjects as? [DataSnapshot] else {return}

                for imageUrl in allImageUrlSnapshot {
                    let imageUrl = imageUrl.value as! String
                    imageUrlArray.append(imageUrl)
                }
            })

            let product = Product(title: title, price: price, imageUrlArray: imageUrlArray, description: description, viewCount: viewCount, id: id)
            productArray.append(product)
        }
        handler(productArray)
    }
}

Ответы [ 3 ]

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

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

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

Вы должны всегда обновлять элементы интерфейса в главном потоке. Здесь тоже не исключение. Просто выполните код перезагрузки в главном потоке.

dispatch_async(dispatch_get_main_queue(), {
   self.mostPopularCollectionView.reloadData()
})

Для Swift 3:

DispatchQueue.main.async { 
   self.mostPopularCollectionView.reloadData()
}
0 голосов
/ 25 августа 2018

ваш viewDidLoad выглядит так:

    var allProducts = [Product]()

override func viewDidLoad() {
   super.viewDidLoad()

    mostPopularCollectionView.dataSource = self
    mostPopularCollectionView.delegate = self

    getAllProducts { (returnedProductArray) in
        self.allProducts = returnedProductArray

     }
   self.mostPopularCollectionView.reloadData()
}
...