Pippo
Pippo

Reputation: 1473

Access nested collectionView in viewController that does not have reference to it

I need to get reference of a collectionView that is nested inside another collectionView so that i can perform UI updates.

In my ViewController class i have an outlet for the "outer" collectionView:

@IBOutlet var outerCollectionView: UICollectionView!

I set the DataSource and Delegate for the "inner" collectionView in willDisplayCell:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    guard let outerViewCell = cell as? OuterCollectionCell else { return }
    outerViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forItem: indexPath.item)
              outerViewCell.innerCollectionView.reloadData()
              outerViewCell.innerCollectionView.layoutIfNeeded()
}

Then i can populate the cells for both collectionViews in cellForItemAt:

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

    if collectionView == self.outerCollectionView {
        let outerCell: OuterCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierOuter, for: indexPath) as! OuterCollectionCell

        outerCell.labelCell.text = self.packArray[indexPath.item].title

        // other stuff....

        return outerCell

    } else {// innerCollectionView
        let innerCell: InnerCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierInner, for: indexPath) as! InnerCollectionCell

        innerCell.imageCell.file = self.multiPartArray[collectionView.tag][indexPath.item].image

        // other stuff....

        return innerCell
    }
 }

This produces the following result:

enter image description here

Where collectionView.tag is the instance of the "inner" collectionView (0 being blue ect).

Now i want to perform UI updates on cells and for various reasons can not use cellForItemAt. So what i have done previously is something like:

if let editCell = collectionView.cellForItem(at: indexPath) as? InnerCollectionCell {
    editCell.imageCell.image = UIImage(named: "test")
}

However to do this i need reference to the "inner" collectionView which i don't have because it may have been reused by the time these UI updates are performed. What i do have however is the collectionView.tag which is just an Int reference and the indexPath of the cell i want to perform the update on.

Can I the UI of the specified cell inside a collectionView that i don't have a direct reference to or is this just wishful thinking?

I should with some sort of delegate function i just cant think how. Also for reference below is my OuterCollection class where i define the "inner" collectionView and set the datasource and delegate.

class OuterCollectionCell: UICollectionViewCell {

@IBOutlet var labelCell: UILabel!
// define the smaller collection view that is in the cell
@IBOutlet var innerCollectionView: UICollectionView!

// set delegate and datasource for new collectionView
// this is download collection manager
func setCollectionViewDataSourceDelegate
    <D: UICollectionViewDataSource & UICollectionViewDelegate>
    (dataSourceDelegate: D, forItem item: Int) {

    innerCollectionView.delegate = dataSourceDelegate
    innerCollectionView.dataSource = dataSourceDelegate
    innerCollectionView.tag = item
    innerCollectionView.reloadData()
    innerCollectionView.layoutIfNeeded()

}
}

Upvotes: 0

Views: 918

Answers (1)

iAviator
iAviator

Reputation: 1447

you can have the delegate and datasource methods of innercollectionview defined in the OuterCollectionCell class. Try this:-

        // Set the delegate and datasource in your custom cell class as below:-
       class OuterCollectionCell: UITableViewCell {
        // set the delegate & datasource of innercollectionView in the init or  
        // awakefromnib or storyboard. 
        // I have set it in storyboard and it works for me. 
        // Implement the datasource and delegate methods of innercollectionView in this class.
       }

This way the delegate and datasource of innerCollectionView will be separate from the outercollectionview and you can handle all the logic of innecrCollectionView in the OuterCollection cell class.

Upvotes: 1

Related Questions