4

I am attempting to set a CollectionView inside of a TableViewCell. I have read through a hand full of stack questions, tuts, and videos and so far I have what appears to be the correct method but my collection view is still not loading into my table view cell.

Code:

import UIKit

class TheaterCell: UITableViewCell {

@IBOutlet var theaterName: UILabel!

@IBOutlet var theaterLocation: UILabel!

@IBOutlet var showtimesCollection: UICollectionView!

override func awakeFromNib() {
    super.awakeFromNib()

    showtimesCollection.delegate = self
    showtimesCollection.dataSource = self
    showtimesCollection.reloadData()

}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

extension TheaterCell: UICollectionViewDataSource, UICollectionViewDelegate {

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

    return 10

}

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

    let cell = showtimesCollection.dequeueReusableCell(withReuseIdentifier: "timeCell", for: indexPath) as! TimeCell

    cell.time.text = "1:00"

    return cell

}

}

The Tableview loads from the ViewController and is displaying its cells and elements but the collection view is not loading within the cell.

3
  • Are your tableview cells appearing ? Commented Dec 10, 2018 at 0:44
  • Yes, as stated in the question the tableview loads and displays the cells. The collection view does not load within the cells. Commented Dec 10, 2018 at 0:46
  • Show the table view’s data source method Commented Dec 10, 2018 at 1:25

2 Answers 2

4

This is working for me, I think the problems comes from the way you register your cell

class YourCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {

@IBOutlet weak var collectionView: UICollectionView!

override func awakeFromNib() {
    super.awakeFromNib()
    registerCell()
    self.collectionView.delegate = self
    self.collectionView.dataSource = self
}
func registerCell() {
    collectionView.register(TimeCell.self, forCellWithReuseIdentifier: "cell")
}
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! TimeCell
    cell.time.text = "1:00"
    return cell
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}
Sign up to request clarification or add additional context in comments.

2 Comments

I get a console error: Could not cast value of type 'UICollectionViewCell' (0x10e36bea0) to 'Film_Bee.TimeCell' (0x10533f688).
I just checked through my table view again and I had not programmatically set the size for the row. Doing this along with your code without the registerCell func works.
1

What I do, I use storyboard and setting the delegates & datasource from Storyboard by dragging into the classes.

a) Set TableView's delegates & datasource to ViewController enter image description here

b) Set CollectionView's delegates & datasource to TableViewCell(TheaterCell) enter image description here

ViewController Code:

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let theaterCell:TheaterCell = tableView.dequeueReusableCell(withIdentifier: "TheaterCell", for: indexPath) as! TheaterCell
    theaterCell.reloadCollectionView()
    return theaterCell
}

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

TheaterCell Code:

class TheaterCell: UITableViewCell {
@IBOutlet var showtimesCollection: UICollectionView!
override func awakeFromNib() {
    super.awakeFromNib()
}

func reloadCollectionView() -> Void {
    self.showtimesCollection.reloadData()
}
}

extension TheaterCell: UICollectionViewDataSource, UICollectionViewDelegate {

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = showtimesCollection.dequeueReusableCell(withReuseIdentifier: "timeCell", for: indexPath) as! TimeCell
    cell.time.text = "1:00"
    return cell
}
}

TimeCell Code:

class TimeCell: UICollectionViewCell {
    @IBOutlet var time: UILabel!
}

Here is the output:

enter image description here

NOTE: IF YOU ARE NOT USING STORYBOARDS AND YOU MAKE COLLECTIONVIEW OR TABLE FROM CODE ONLY, THEN YOU HAVE REGISTER YOURS CELL AS: A) TheaterCell must be registered into ViewController class B) TimeCell must be registered into TheaterCell class

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.