Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionViewCell embedded in UITableViewCell changes scroll position when re-appears

I have a tableview with the cells having a horizontal collection view. I have multiple cells with the same style. Let's say tableView cells at indices 0 & 5 have the same style (I am using the same UITableViewCell subclass in dequeueReusableCellWithIdentifier).

  1. User scrolls to tableViewCell at index 5. He scrolls the horizontal collection view leftwards(let's say that the red-1 and yellow-2 cells are now hidden, cyan-3 is the leftmost).
  2. User scrolls back to tableViewCell at index 0. Although it's a different UITableViewCell instance, the collection view offset is set to the same as the cell at index 5.

enter image description here

In short, when I'm re-using tableview cells, the content offset of the scroll view inside the UITableViewCell is being set to the previous re-used cell.

Is there someway I can disable this behaviour, so that each cell maintains it's own offset regardless of any scroll activity on another cell.

like image 701
Raunak Avatar asked Sep 22 '16 12:09

Raunak


1 Answers

You can achieve this by adding the following methods to your custom cell class:

public func setScrollPosition(x: CGFloat) {
    collection.setContentOffset(CGPoint(x: x >= 0 ? x : 0, y: 0), animated: false)
}

public func getScrollPosition() -> CGFloat {
    return collection.contentOffset.x
}

And the following in your table view data source class:

var offsets = [IndexPath:CGFloat]()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.setScrollPosition(x: offsets[indexPath] ?? 0)
    return cell
}

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    offsets[indexPath] = collectionCell.getScrollPosition()
}
like image 140
RoyR Avatar answered Oct 30 '22 14:10

RoyR