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,

  1. Get a new cell - When the tableViewCell is reused, the collectionView inside it also will be reused and so this is the reason the contentOffset of the previous cell is retained.

  2. Scroll to previous cell - if we've manually scrolled to a particular cell in the collectionView, 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.

  1. In storyboard, create a UIScrollView. Add a vertical UIStackView to it.

  2. Add 4 UICollectionViews in the stackView. This number is configurable as per your requirement.

  3. Add your controller as the dataSource and delegate of all the collectionViews.

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.

enter image description here


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 .