-1

I have a UITableView which has 2 sections. In section 1 is a static cell which has a horizontal collectionView inside it.

My question is how do I reference the collectionView in the Controller to reload the collectionView...

Here is my code:

TableView Controller

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

    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "collectionCellID", for: indexPath) as! CollectionTableViewCell

        return cell

    } else {

        let cell = tableView.dequeueReusableCell(withIdentifier: "tableCellID", for: indexPath) as! TableCell

        return cell
    }
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if indexPath.row == 0 {
        if let cell = cell as? CollectionTableViewCell {
            cell.collectionView.delegate = self
            cell.collectionView.dataSource = self
            cell.collectionView.contentInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
        }
    }
}

TableView Cell

class CollectionTableViewCell: UITableViewCell {

@IBOutlet weak var collectionView: UICollectionView!

}

CollectionView extension

extension MyController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

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

    return cell
}

Data call in TableViewController

public func getData() {

    ref.observe(.childAdded, with: { (snapshot) in

                self.data.append(snapshot)
            }

            DispatchQueue.main.async {
                //MARK: - collectionView.reloadData() <- not available
            }
        }
    })
}
David Henry
  • 1,972
  • 20
  • 43

3 Answers3

0

Call the table view's cellForRow(at:) to get a reference to the cell at section 0 row 0, cast that reference to a CollectionTableViewCell, and refer to its collectionView.

matt
  • 515,959
  • 87
  • 875
  • 1,141
0

I had a tough time to configure the same issue (https://stackoverflow.com/a/45618501/3400991) . Here is few points regarding this :

  1. Your Controller should conforms UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
  2. Create CollectionView cell and set its custom class into CollectionView cell .
  3. Tableview dont have any idea about how much height its cell needed to render complete collectionview data inside tableview cell so you have to use this :

    yourTableView.rowHeight = UITableViewAutomaticDimension yourTableView.estimatedRowHeight = 90

  4. Set Height of Tableview accordingly :

// since Collectionview explicitly telling its Parent to provide height

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

    //Checking MIME Type
    if condition for collectionview cell {
        // set here 
    }
    //Normal autolayout cell
    else {
        return UITableViewAutomaticDimension
    }
}
  1. Make Collectionview reference in Tableview Custom Cell class :

class customTableViewCell: UITableViewCell { @IBOutlet weak var collectionview: UICollectionView }

  1. Inside Tableview willDisplayCell :

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

            cell.collectionview.delegate = self
            cell.collectionview.datasource = self
            //Reload it also
            cell.collectionview.reloadData()
    }
    
Shobhakar Tiwari
  • 7,862
  • 4
  • 36
  • 71
  • 1
    I can't have cell.collectionView.reloadData() in willDisplayCell, as each time the user scrolls up and down the cell will keep displaying. Resulting in the collectionView being unnecessarily reloaded – David Henry Sep 03 '17 at 20:09
  • otherwise , you should use collectionview instead and make use of as tableview along with collectinoviw – Shobhakar Tiwari Sep 03 '17 at 20:17
  • Then I would have the reverse problem. If I was to follow MVC I wouldn't be able to access my tableView to reload it... Which is the same problem I'm having with collectionView... – David Henry Sep 03 '17 at 20:28
0

So what I ended up doing was creating a Header View for the table and adding a collectionView to it.

func configureHeaderView() {

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    layout.sectionInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)

    collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 105), collectionViewLayout: layout)
    collectionView.backgroundColor = UIColor(red: 248/255, green: 248/255, blue: 248/255, alpha: 1)
    collectionView.isPagingEnabled = false
    collectionView.isUserInteractionEnabled = true
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.register(UINib(nibName: "cell", bundle: nil), forCellWithReuseIdentifier: "cell")
    collectionView.showsHorizontalScrollIndicator = false

    tableView.tableHeaderView = collectionView
}

Then from anywhere I can now access:

DispatchQueue.main.async {
               self?.collectionView.reloadData()
            }
David Henry
  • 1,972
  • 20
  • 43