Reputation: 151
I created collection view in a tableview for scrolling two dimension (horizontal - vertical) And I fetch data from JSON API everything is working fine in first attempt but there is the problem when I scrolling to down:
Collection View fetching duplicated data. It displaying wrong image and text data in cell.
How can i fix this situation ? Code like below.
This one is my main TableView’s cellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: exploreCellIDColl, for: indexPath) as! TableExploreCell
cell.postCategory = exploreCategories?[indexPath.row]
return cell
}
This one is CollectionView cellForItemAt in TableViewCell:
// I created collection view in tableview cell
let cellCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let collView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collView.backgroundColor = .clear
return collView
}()
// This part showing duplicated wrong data (image and text)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: exploreCellID, for: indexPath) as! CollectionExploreCell
cell.postsExplore = postCategory?.post?[indexPath.row]
self.postCategory?.post?.append(contentsOf: model.data ?? [])
self.cellCollectionView.reloadData()
return cell
}
Upvotes: 1
Views: 2220
Reputation: 131511
This is a common issue everybody encounters with collection views and table views when they first start using them. The issue is that cells get recycled. When you call dequeueReusableCell after scrolling, you are likely to get passed a cell that just scrolled off-screen and has contents in its view from the last use. You have to make your cellForItemAt/cellForRowAt code always set a value for every field, regardless of the model data.
Your cellForItemAt()
code uses optional chaining to only set cell views if various parts of your model are not nil (the question marks in postCategory?.post?[indexPath.row]
and the line below). You need to instead use if let
or some other approach that always sets each field to a value, and sets it to an empty value if the corresponding part of your data model is nil.
Also note that you should not ever call reloadData()
inside cellForItemAt
. That will cause an endless loop where the collection view tries to return a cell, then throws all the cells away and starts loading new ones, but each time it returns a new cell, throws them all away again.
Upvotes: 4