Christian
Christian

Reputation: 75

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!

}

Upvotes: 0

Views: 516

Answers (2)

Christian
Christian

Reputation: 75

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)
    }

Upvotes: 3

Adi.S
Adi.S

Reputation: 280

Try adding some animation like loading screen this looks better on User Interface perspective too.

Use third party libraries like MBProgressHUD this way your app look more cleaner, for installtion details check the link please.

After adding MBProgressHUD your code look like ...

Create a simple resuable function (calling it easy anytime you need it)

func needSomeAnimation(msg: String, mode: MBProgressHUDMode){
        let loadingNotification = MBProgressHUD.showAdded(to: self.view, animated: true)
        loadingNotification.mode = mode
        loadingNotification.label.text = msg
        loadingNotification.hide(animated: true, afterDelay: 2.0)
    }

Now call it were you need it.

@IBAction func touchButton(_ sender: Any) {

    needSomeAnimation(msg: "Loading", mode: MBProgressHUDMode.indeterminate)

    if datasource[0] == 1 {
        datasource[0] = 3
    } else {
        datasource[0] = 1
    }
    cellectionview.reloadItems(at: [IndexPath(item: 0, section: 0)])
}

I hope my solution works for you : D

Upvotes: 0

Related Questions