简体   繁体   中英

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) and reloadData() , cause all cells to slightly flicker (which would be ok) but cause all progress bars to completely disappear after the first update.
  • setNeedsLayout() and setNeedsDisplay() seem to have no effect at all. Nothing (visible) happens.

All methods were called in on self.collectionView 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?

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  
   CollectionView.reloadData()}

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

After I implemented an automatic update for the cells in a separate queue (as user2718075 suggested), I still had the problem of disappearing views. This would happen every time the view(s) with the progress bars would disappear from sight when I scrolled and looked at other cells where I hid the progress bar through customProgress.hidden = true , because they were done.

This made me realize that this issue had to do with cell reuse. The cells with the progress bars would be used for another cell without a progress bar, thus it was hidden. After dequeuing and reusing it again for a cell that needed a progress bar, I did not call customProgress.hidden = false . After adding that line to the cell configuration, the problem was gone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM