Eu tenho uma visualização de tabela onde cada célula contém uma visualização de coleção. Cada visualização da coleção possui uma apresentação de slides horizontal de imagens. Cada célula de visualização de tabela é configurada com um modelo de visualização, que contém uma matriz de imageURLs para a visualização de coleção aninhada usar como fonte de dados. Tudo funciona bem até que preciso carregar minha segunda página de dados. Depois de carregar minha segunda página de dados na visualização de tabela, os itens da segunda página parecem ser duplicatas dos itens da primeira página. Mas é estranho porque também tenho um controle de página nesta visualização de coleção que está configurado com a contagem do array imageURLs, e o número de páginas está correto. Apenas as próprias imagens estão duplicando a primeira página.
Aqui está o cellForRow na visualização da tabela:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: DataTableViewCell.id, for: indexPath) as! DataTableViewCell
cell.delegate = self
cell.configureWith(viewModel.getViewModelAt(indexPath.row))
return cell
}
Aqui está o cellForItem na visualização da coleção aninhada:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.row == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CensoredDataCollectionViewCell.id, for: indexPath) as! CensoredDataCollectionViewCell
cell.setRemoteImage(with: viewModel.photoGalleryURLStrings[0])
return cell
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageCollectionViewCell.id, for: indexPath) as! ImageCollectionViewCell
let imageURLString = viewModel.photoGalleryURLStrings[indexPath.row - 1]
cell.setRemoteImage(with: imageURLString)
return cell
}
O setRemoteImage
método apenas define a visualização da imagem da célula a partir de uma imagem no servidor. Isso indexPath.row - 1
ocorre porque a visualização da coleção possui uma célula extra no início.
Aqui está o código no controlador de visualização que faz uma nova chamada de rede ao chegar ao fundo:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == viewModel.dataCount - 1 {
tableViewFooterLoadingWheel.startAnimating()
viewModel.downloadData { [weak self] moreData in
if moreData {
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}
DispatchQueue.main.async {
self?.tableViewFooterLoadingWheel.stopAnimating()
}
}
}
}
Aqui está o caso de sucesso da chamada de rede onde novos itens são anexados à fonte de dados:
case .success(let result):
strongSelf.data.append(contentsOf: result.results)
if let next = result.next {
strongSelf.dataURL = next
} else {
strongSelf.dataURL = nil
}
completion(true)
Para teste, a chamada de rede inicial me dará 5 itens para minha visualização de tabela. Os dois primeiros itens possuem apenas uma imagem para a visualização da coleção aninhada. Depois de carregar minha segunda página, que para fins de teste possui apenas 2 itens, esses dois itens têm as mesmas imagens que os dois primeiros na página 1. Mas, como mencionei, o número de páginas de controle de página é mapeado para o número correto de URLs de imagem . Então, em algum lugar a contagem de imagens está completamente correta. Apenas não a imagem real.
Desculpas se algum deste código não for necessário. Por favor, não recomende que eu redefina o conteúdo em prepareForReuse() a menos que isso seja tudo que posso fazer, como a Apple diz para não fazer isso. Desde já agradeço se puder me ajudar.
Editado para incluir a função configureWith():
func configureWith(_ viewModel: dataViewModel) {
self.dataViewModel = viewModel
loadingWheel.startAnimating()
avatarImageView.loadImageFromURL(dataViewModel.avatarImageURLString) { [weak self] in
DispatchQueue.main.async {
self?.loadingWheel.stopAnimating()
}
}
statusLabel.text = dataViewModel.status
createdAtLabel.text = dataViewModel.created
photoGalleryPageControl.numberOfPages = dataViewModel.photoGalleryURLStrings.count
likesCountLabel.text = "\(dataViewModel.likeCount)"
likesButton.isSelected = dataViewModel.isLiked
commentsCountLabel.text = dataViewModel.commentCount
}
As células da visualização de tabela são reutilizadas ...
Como você viu, você precisa chamar
.reloadData()
a visualização de coleção incorporada ao definir novos dados para a célula.Para o segundo problema - a visualização da coleção incorporada não é "recriada" quando a célula é reutilizada. Isso significa que sua posição de rolagem (seu deslocamento de conteúdo) não muda.
Se quiser que a visualização da coleção comece na primeira célula sempre que uma linha for rolada para view , você também precisará chamar:
quando a célula é configurada/mostrada.
Se você deseja que a posição de rolagem da visualização da coleção permaneça a mesma enquanto você rola a tabela, ou seja:
então você precisará rastrear o deslocamento do conteúdo da visualização da coleção em seu controlador de visualização de tabela para cada linha.