I'm trying to put a UICollectionView
within each reusable UICollectionViewCell
. The Ash Furrow method didn't work out too well for me, because using one UICollectionViewController
class for the data source and delegate of two UICollectionViews
does not work.
My latest approach is to put the view of a UICollectionViewController
inside each cell, as described in this question and this doc. However, when I go try to load the view, my app freezes. In the Xcode debug navigator, the CPU is at a constant 107% and the Memory approaches 1GB after a few seconds.
In this example, I am trying to get a ThumbnailCollectionViewController
in each MainCollectionViewControllerCell
. The only thing in each ThumbnailCollectionViewControllerCell
is an image of size 50x50.
How is this done properly?
In MainCollectionViewController
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell
let thumbsViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ThumbnailColllection") as! ThumbnailCollectionViewController
self.addChildViewController(thumbsViewController)
thumbsViewController.view.frame = cell.bounds
cell.addSubview(thumbsViewController.view)
thumbsViewController.didMoveToParentViewController(self)
}
ThumbnailCollectionViewController
let reuseIdentifier = "ThumbCell"
let thumbnails = ["red", "green", "blue"]
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return thumbnails.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell
let cellImage = UIImage(named: thumbnails[indexPath.row])
let cellImageView = UIImageView(image: cellImage)
cellImageView.frame = cell.bounds
cell.addSubview(cellImageView)
return cell
}
Your approach to putting a UICollectionView
inside each cell looks fine, but you are most likely seeing atrocious performance because you are mishandling cell reuse. You are adding a new collection view to the cell (and actually, a new image view to every thumbnail cell) EVERY time a new reusable cell is requested. If you scroll continuously, then cells will be dequeued that already have these subviews added, so you will end up with many many subviews under each cell.
Instead, add a means of checking whether a cell already has the subview or not, and only add it if it doesn't. Probably the best way is by using a custom cell subclass:
class ThumbnailCollectionCell: UICollectionViewCell {
var thumbnailViewController: ThumbnailCollectionViewController?
}
Back in your MainCollectionViewController:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! ThumbnailCollectionCell
if cell.thumbnailViewController == nil {
let thumbsViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ThumbnailColllection") as! ThumbnailCollectionViewController
self.addChildViewController(thumbsViewController)
thumbsViewController.view.frame = cell.bounds
cell.addSubview(thumbsViewController.view)
thumbsViewController.didMoveToParentViewController(self)
cell.thumbnailViewController = thumbsViewController
}
}
And again, something similar to prevent multiple UIImageView
s being added to each thumbnail cell.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With