UICollectionView, вложенный в UITableViewCell, не обновляется с использованием DispatchQueue после получения новых данных - PullRequest
0 голосов
/ 07 июня 2018

У меня есть 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()
        }
    })
}

noteпервое, что я делаю, это удаляю все данные из 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 ]

0 голосов
/ 07 июня 2018

Ваши коды:

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
    }

Например, если текущий indexPath равен (1, 0), но ячейка повторно используется из indexPath (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
0 голосов
/ 07 июня 2018

Вы не должны звонить dequeueReusableCell где-либо, кроме cellForRowAt.

. Чтобы получить отображаемую в данный момент ячейку (если есть), вы используете cellForRowAt:;это может вернуть nil, если строка в данный момент не отображается на экране.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...