Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView within a UICollectionViewCell (Swift)

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
}
like image 483
natec Avatar asked Dec 24 '22 15:12

natec


1 Answers

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 UIImageViews being added to each thumbnail cell.

like image 184
Stuart Avatar answered Jan 04 '23 17:01

Stuart