0
votes

I’ve got a tableView with collectionViews nestled in each tableViewCell. Each tableViewCell is a movie genre and the collectionViewCells would be the movies. I’m trying to tell the collectionView which TableView indexPath it is so it can display the correct data.

The problem I’m having is as you scroll through the collectionView (and TableView) the numbers change (I’ve got a label in the collectionView cell displaying the TableView indexPath.row). Also if I scroll to the end of a collectionView in the first tableView cell, the collectionViewCell in the 4th or so tableViewCell will also be scrolled to the end, as if they are ‘linked’.

To get the nestled layout I’m following this tut https://youtu.be/4XnXHov2lQU I’d initially setup the collectionView from the TableViewCell Class but as explained in the video this doesn’t conform to MVC.

To get the tableViewIndexPath I just set a variable in the TableView cellForRowAt then set the label in the collectionView to this.

What would be the correct way to do this as I’ve seen other questions and answered posted on this but pretty much all give the same problem.

EDIT - TableViewController.swift

class TableViewController: UITableViewController {

    var tableViewIndexPath = Int()

    override func viewDidLoad() {
        super.viewDidLoad()          
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 230
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! tableViewCellClass

        tableViewIndexPath = indexPath.row

        cell.collectionView.dataSource = self
        cell.collectionView.reloadData()

        return cell
    }
}

extension TableViewController : UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath)

        let title = cell.viewWithTag(4) as! UILabel
        title.text = String(tableViewIndexPath)

        return cell
    }

}

TableViewCellClass.swift

class tableViewCellClass: UITableViewCell {
    @IBOutlet weak var collectionView: UICollectionView!

    var indexPathForCell: IndexPath?

    override func prepareForReuse() {
        self.collectionView.contentOffset = .zero
        self.collectionView.reloadData()
    }
}
2

2 Answers

2
votes

Your question clearly has a lack of code, but from your description, I suppose that you have a problem with cells reusing.

Let's say, that you scrolled UICollectionView at the first cell to the right. If after that, you start to scroll you UITableView down, your UITableViewCells will be recused. So your 4th UICollectionView will be in fact, the first cell that had been reused. Reused means that it is the very same cell. And since you scroll the first cell to the right, its CollectionView has the same contentOffset value and it looks like it was scrolled.

Every reusable cell has a method prepateForReuse() that can be overridden. In that method, you can reset all your cell parameters to default values. For example, I'll assume that, at your table view cell class, you have a collectionView object. In that case, you need to do next

override func prepareForReuse() {
    self.collectionView.contentOffset = .zero
}

After that, every reused cell will be automatically returned to its initial position. Also, when you'll scroll you table view back to the top, the first UICollectionView will be at the initial position as well.

0
votes

In your tableview cell class add extension of collectionview delegate and data source, define your layout and configure collectionview cells.

In your view controller class go to cellForRowAIndex and call the method of tableview cells class like configureCollectionView(at section: indexPath.row) // to capture the row index

In your tableview class make sure you define configure method that sets the collectionview delegate, datasource and reloads data

Doing this will allow you to keep the scroll positions of each row to be scrolled in a way that doesn't seemed linked.