Jack Wu
Jack Wu

Reputation: 37

How does UICollectionView update the cells?

I am building an app that tracks packages. Each cell in the UICollectionView contains the name of the package and the delivery status of the package. My data source for the collection view is an array of items.

The Item class looks something like this:

class Item {
    var name: String
    var carrier: String 
    var trackingNumber: String 
    var status: String //obtained via API get request at some point after initialization 
}

I would like to implement two functions: the ability to add an item (and subsequently trigger an update for all items) and the ability to just trigger an update for all items. Here is what my ViewController basically looks like:

class PackagesController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    var items: [Item]? 
    override func viewDidLoad() {super.viewDidLoad()}
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        //return an item cell 

        //Is this where I should make the API request? 

    }
}

My questions are:

  1. Where should I make the API request (for maximum efficiency)?

  2. How can I update all the items' info upon the user's request (not sure if looping through the items array would cause the collection view to reload)?

  3. Is there something inherently wrong with the way my code is currently structured or is there a better way to organize my code for the desired purposes?

Upvotes: 0

Views: 210

Answers (1)

Gereon
Gereon

Reputation: 17882

Your code as written looks mostly OK so far.

Some changes I would recommend:

  • Item should be a struct, not a class, and its members should be constant (let), unless you have very good and specific reasons otherwise.
  • "obtained via API get request at some point after initialization" sounds like this should be an Optional (String?)

Is this where I should make the API request?

No. Never do network requests or anything complicated in cellForItemAt. Simply get the appropriate record from your data source (i.e. your array of items), and populate the cell with that.


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    // get a cell
    let cell = collectionView.dequeueResuableCell(withIdentifier: "yourCellIdentifier", indexPath: indexPath) as! YourCellClass
    // get the data
    let item = self.items[indexPath.row]
    // populate the cell with the data
    cell.setup(with: data) // you need to implement this in your cell

    return cell
}

How can I update all the items' info upon the user's request

Make the corresponding network request / calculations or whatever is necessary, and once you have the result, overwrite your items array and call reloadData() on the CollectionView. Put this in a method you can call e.g. as the action of a button tap, and of course when your collection view is initially displayed.

Upvotes: 0

Related Questions