代码之家  ›  专栏  ›  技术社区  ›  Jordan Lewallen

UITableViewCell中嵌套的UICollectionView在收到新数据后不会使用DispatchQueue进行更新

  •  0
  • Jordan Lewallen  · 技术社区  · 6 年前

    我有一个 UICollectionView 嵌套在 UITableViewCell :

    enter image description here

    集合视图单元格中的数字会在不同的视图中更新,因此当我返回此屏幕时,我希望能够刷新视图,新的数字会反映在它们的单元格中。我有一个叫 topUserModel 在我的集合视图中,我使用firebase数据库中的数据进行填充。当我下拉刷新时,以下函数会在我的主表视图中运行:

    @objc func refreshView(refreshControl: UIRefreshControl) {
    
            DispatchQueue.main.async {
                //this is the row that the collection view is in
                if let index = IndexPath(row: 1, section: 0) as? IndexPath {
                    if let cell = self.homeTableView.cellForRow(at: index) as? TopUserContainerViewController {
                        cell.userCollectionView.reloadData()
                    }
                }
            }
            refreshControl.endRefreshing()
        }
    

    然后运行我的 awakeFromNib() 在集合视图中触发:

    func fetchTopUsers() {
        topUserModel.removeAll()
        let queryRef = Database.database().reference().child("users").queryOrdered(byChild: "ranking").queryLimited(toLast: 10)
        queryRef.observe(.childAdded, with: { (snapshot) in
            if let dictionary = snapshot.value as? [String : AnyObject] {
                let topUser = TopUser(dictionary: dictionary)
                self.topUserModel.append(topUser)
            }
    
            DispatchQueue.main.async {
                self.userCollectionView.reloadData()
            }
        })
    }
    

    请注意,我要做的第一件事是从数据库中删除所有数据 topUserModel 。在存储新数据并附加它(见上文)后,我可以将该代码块中的整数值打印到屏幕上,并显示为更新后的值。 然而,在我的集合视图(见下文)中,如果我在这里的任何一点打印出整数值(它被称为 watchTime ),即使 topUserModel 是否已清除并添加了新数据?:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "topUserCell", for: indexPath) as! TopUsersViewController
    
            if topUserModel.count > indexPath.row {
                //image stuff redacted
                Nuke.loadImage(
                    with: ImageRequest(url: url).processed(with: _ProgressiveBlurImageProcessor()),
                    options: options,
                    into: cell.topUserImage
                )
                cell.topUserName.text = topUserModel[indexPath.row].username
                cell.topUserMinutes.text = "\(String(describing: topUserModel[indexPath.row].watchTime!))"
            }
            return cell
        }
    

    enter image description here

    2 回复  |  直到 6 年前
        1
  •  1
  •   Paulw11    6 年前

    你不应该打电话 dequeueReusableCell 在任何地方 cellForRowAt .

    以获取当前显示的单元格(如果有) cellForRowAt: ; 这可能会回来 nil

    一旦有了单元格,就可以重新加载其数据并刷新其集合视图。

        2
  •  0
  •   AechoLiu    6 年前

    您的代码:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "topUserCell", for: indexPath) as! TopUsersViewController
    
            if topUserModel.count > indexPath.row {
                //image stuff redacted
                Nuke.loadImage(
                    with: ImageRequest(url: url).processed(with: _ProgressiveBlurImageProcessor()),
                    options: options,
                    into: cell.topUserImage
                )
                cell.topUserName.text = topUserModel[indexPath.row].username
                cell.topUserMinutes.text = "\(String(describing: topUserModel[indexPath.row].watchTime!))"
            }
            return cell
        }
    

    例如,如果当前的indexath是 (1, 0) ,但该单元格是从一个独立的XPath中重用的 (100, 0) 。因为它不在屏幕上,可以重复使用以显示新内容。

            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "topUserCell", for: indexPath) as! TopUsersViewController
    

    if topUserModel.count > indexPath.row {
       // ... Update to new content
    }
    
    // If topUserModel.count <= indexPath.row, then the cell content is undefined.
    // Use the original content of reuse cell. 
    // Ex, it may be come from (100, 0), but current indexPath is (1, 0).
    // ...
    
    // You can add a property to the cell to observe the behavior.
    if (cell.indexPath != indexPath) {
        // Ops .... 
    }
    
    // Update to current indexPath
    cell.indexPath = indexPath
    return cell