UICollectionView reuse in UITableViewCell
UITableView
works on the concept of reusability
. Whenever the tableView
is scrolled, the cells
in the tableView
will definitely be reused.
Now 2 scenarios arise with this,
Get a new cell - When the
tableViewCell
is reused, thecollectionView
inside it also will be reused and so this is the reason thecontentOffset
of the previous cell is retained.Scroll to previous cell
- if we've manually scrolled to a particularcell
in thecollectionView
, we might want to retain its position when we scroll back to it.
To get this kind of functionality in tableView
, we need to - manually reset the contentOffset
for 1st case
and need to retain the contentOffset
in the 2nd one.
Another approach you can follow is using a combination of UIScrollview and UIStackView
.
This is how it goes.
In
storyboard
, create a UIScrollView. Add a vertical UIStackView to it.Add 4
UICollectionViews
in thestackView
. This number is configurable as per your requirement.Add your
controller
as thedataSource
anddelegate
of all thecollectionViews
.
i.e.
class ViewController: UIViewController, UICollectionViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
cell.label.text = "\(indexPath.row)"
return cell
}
}
class CustomCell: UICollectionViewCell {
@IBOutlet weak var label: UILabel!
}
Now, since we're using a stackView
, none of the collectionViews
will be reused. So, the contentOffsets
of the all the collectionViews
will remain intact.
There are two scenarios.
1 - Reset The UICollectionView offset position :
To Reset the collectionview position just call cell.collectionView.contentOffset = .zero
in cellForRowAtIndexPath
2 - Maintain the previous scroll position :
To Maintain the previous scroll position, You'll need to have a list of offsets for each cell stored alongside your data models in the containing view controller. Then you might save the offset for a given cell in didEndDisplayingCell
and setting it in cellForRowAtIndexPath
instead of .zero
.