Reputation: 1473
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:
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
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