Search code examples
swiftuicollectionviewoverlayreloadreloaddata

Value of a Label inside a CollectionView Cell is overlapping old value for a millisecond while reloadItems()


I already asked a question for this behavior. I think you understand what I mean if not please ask. So I have a little demo project with a collectionView and a datasource with integers in it. In my project I must refresh the cells by calling reloadItems(at: at: [IndexPath]) because of lower cpu usage. But when I refresh a cell with reloadItems(at: at: [IndexPath]) I can see for a millisecond the old value from the cells label. It looks not perfect.

Here is my code from ViewController.swift

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return datasource.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let mycell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell

    mycell.cellvalue.text = String(datasource[indexPath.row])
    return mycell
}


@IBOutlet weak var cellectionview: UICollectionView!
@IBAction func touchButton(_ sender: Any) {
    if datasource[0] == 1 {
        datasource[0] = 3
    } else {
        datasource[0] = 1
    }
    cellectionview.reloadItems(at: [IndexPath(item: 0, section: 0)])
}

var datasource: [Int] = [1, 2, 3, 4, 5, 6]


override func viewDidLoad() {
    super.viewDidLoad()
    cellectionview.dataSource = self
    cellectionview.delegate = self
    // Do any additional setup after loading the view, typically from a nib.
}

}

Very simple. When I touch the button the first value of the datasource changes and I simply call the reload items function only for the first cell.

Thats the code for my CustomCell:

class MyCell: UICollectionViewCell {
@IBOutlet weak var cellvalue: UILabel!

}


Solution

  • With reloadItems(at: [IndexPath]) the CollectionView automatically updates the values with the default animation FadeInOut. You can avoid this animation by simply call the function func performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil) and with an animation block and set the time to 0.0.

    UIView.animate(withDuration: 0) {
            self.cellectionview.performBatchUpdates({
                self.cellectionview.reloadItems(at: [IndexPath(item: 0, section: 0)])
            }, completion: nil)
        }