Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested Collection View inside of table view cell swift iOS

I am nesting a collection view inside of a table view cell. I need to implement a screen similar to that of the app store of netflix. Where you have categories such as enter image description here

I would need to load the data from a JSON, for instance - "Popular" may have 11 videos, "Action" May have 3 videos and "Adventures" may have 20. So inside each table view cell, that specific collection view would load a different number of collection view cells depending on how many videos are in each category (Popular, Action, Adventure), which will be displayed within its own respective horizontal collection view.

So far with my code i display each category title in the table view header. But within that category, inside the collection view numberOfItemsInSection and cellForItemAt, i can't find a way to load each collection view interdependently. For example, collection view 1 that relates to Popular, should load 11 cells, Collection View 2 which relates to Action should load 3 cells. Below is my code so far

My TABLE VIEW METHODS WHICH ARE INSIDE OF VIEW CONTROLLER

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "categoriesCell") as? CategoriesTableViewCell else { return UITableViewCell() }

    return cell
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    return arrayOfCategoryObjects[section].title
}

func numberOfSections(in tableView: UITableView) -> Int {
    return arrayOfCategoryObjects.count
}

 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    if let cell = cell as? CategoriesTableViewCell {


        cell.moviesCollectionView.dataSource = self
        cell.moviesCollectionView.delegate = self

        cell.moviesCollectionView.reloadData()

    }
}

MY TABLE VIEW CELL

class CategoriesTableViewCell: UITableViewCell {

@IBOutlet weak var moviesCollectionView: UICollectionView!

}

MY COLLECTION VIEW DELEGATES WHICH ARE ALSO INSIDE THE VIEW CONTROLLER

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

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
   // print(arrayOfCategoryObjects[section].movies[section])

    return arrayOfCategoryObjects[section].movies.count

  }

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "moviesCell", for: indexPath) as! MoviesCollectionViewCell

        cell.movieTitleLbl.text = arrayOfCategoryObjects[indexPath.item].movies[indexPath.item]

        return cell

  }

MY COLLECTION VIEW CELL

class MoviesCollectionViewCell: UICollectionViewCell {

@IBOutlet weak var movieTitleLbl: UILabel!

}
like image 347
Coding while Loading Avatar asked Jan 24 '20 17:01

Coding while Loading


1 Answers

You need to set a tag for your UICollectionView as parent UITableViewCell's indexPath.section:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    if let cell = cell as? CategoriesTableViewCell {

        cell.moviesCollectionView.dataSource = self
        cell.moviesCollectionView.delegate = self
        cell.moviesCollectionView.tag = indexPath.section
        cell.moviesCollectionView.reloadData()

    }
}

and then in your UICollectionView's delegate:

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

    return arrayOfCategoryObjects[collectionView.tag].movies.count

  }

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "moviesCell", for: indexPath) as! MoviesCollectionViewCell

    cell.movieTitleLbl.text = arrayOfCategoryObjects[collectionView.tag].movies[indexPath.item]

    return cell

  }

Hope this helps!

like image 181
sandpat Avatar answered Oct 25 '22 19:10

sandpat