NerdyTherapist NerdyTherapist - 1 year ago 167
Swift Question

Custom CollectionView cells' layout elements disappear when attempting to update the cell

I have a custom cell for a collection view, which is set in the storyboard and has outlets connected to a corresponding cell class.

class MyCustomCollectionViewCell: UICollectionViewCell {

// MARK: Outlets

@IBOutlet weak var customImage: UIImageView!
@IBOutlet weak var customProgress: UIProgressView!
@IBOutlet weak var customLabel: UILabel!


The initial setup works perfectly, I am setting a custom image, name and progress according to a particular state of an item in my database.

I want to update the collection view to reflect changes, especially regarding the status bar. Also, once the status bar is finished, the image should change also.

timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: #selector(MyViewController.updateUI), userInfo: self, repeats: true)

Using a timer started when the view appears, I want to update the view every couple of seconds (I chose 3 to effectively test it, but it could also be as long as maybe 20 seconds).

The problem is, I don't know what method to use here, as the all have specific drawbacks:

  • reloadSections(mySection)
    , cause all cells to slightly flicker (which would be ok) but cause all progress bars to completely disappear after the first update.

  • setNeedsLayout()
    seem to have no effect at all. Nothing (visible) happens.

All methods were called in on
like so:

@objc private func updateUI() {
// self.collectionView?.reloadSections(singleSection)
// self.collectionView?.reloadData()
// self.collectionView?.setNeedsLayout()
// self.collectionView?.setNeedsDisplay()

(I tried them all one by one)

How can I update my view (automatically) without the progress bars disappearing?

Answer Source

I think that you can use dispatch_async, that runs in another thread.

Put a flag in collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath), if true change only the image.

In the cell, start a loop on progress with

dispatch_async(dispatch_get_main_queue(), {
    //do staff to controle your progress state
    // set your flag to true if progress is ok 
    // if ok then reload the collection  

Now the flag is true, update your image. Haven't tried it, but I think that it could be a possible way.