user1105951
user1105951

Reputation: 2287

Is there a way to -preload- UICollectionViewCell?

Something that bother me for a long time.

Is there a way to preload UICollectionViewCell ? something to prepare before loading the data, so the cell will not be create while user is scrolling.

Is there a way to take Full control on WHEN to create the UICollectionViewCell and WHEN to destroy the UICollectionViewCell.

Upvotes: 0

Views: 3396

Answers (3)

hh3n7a1
hh3n7a1

Reputation: 91

I can add some actual approach

If you need to preload some data from internet / core data checkout https://developer.apple.com/documentation/uikit/uicollectionviewdatasourceprefetching/prefetching_collection_view_data

tl;dr

first you need your collection view datasource to conform UICollectionViewDataSourcePrefetching in addition to UICollectionViewDataSource protocol

then prefetch your data and store it in cache

func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
    // Begin asynchronously fetching data for the requested index paths.
    for indexPath in indexPaths {
        let model = models[indexPath.row]
        asyncFetcher.fetchAsync(model.id)
    }
}

and finally feed your cell with your cached data

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.reuseIdentifier, for: indexPath) as? Cell else {
        fatalError("Expected `\(Cell.self)` type for reuseIdentifier \(Cell.reuseIdentifier). Check the configuration in Main.storyboard.")
    }

    let model = models[indexPath.row]
    let id = model.id
    cell.representedId = id

    // Check if the `asyncFetcher` has already fetched data for the specified identifier.
    if let fetchedData = asyncFetcher.fetchedData(for: id) {
        // The data has already been fetched and cached; use it to configure the cell.
        cell.configure(with: fetchedData)
    else
        ... async fetch and configure in dispatch main asyncd

Also u can approach some workaround using delegate methods to handle willDisplay, didEndDisplay events e.g. https://developer.apple.com/documentation/uikit/uicollectionviewdelegate/1618087-collectionview?language=objc

Upvotes: 0

Daniel Sumara
Daniel Sumara

Reputation: 2264

You can blackout your screen while you enter into scene and navigate (scroll) to each cell type. When you did scroll each cell you should hide blackout view and present collection view on first cell (top).

It is some kind of workaround. My cells have a lot resources like images, which lag while scrolling collection view.

Upvotes: 0

slashdot
slashdot

Reputation: 630

From Apple documentation:

You typically do not create instances of this class yourself. Instead, you register your specific cell subclass (or a nib file containing a configured instance of your class) with the collection view object. When you want a new instance of your cell class, call the dequeueReusableCell(withReuseIdentifier:for:) method of the collection view object to retrieve one.

The cell itself is not a heavy resource, so it makes a little sense to customize its lifetime. I think that instead of searching for a way to take a control over cell creation, you should ask yourself: why do you want to preload a cell? What kind of heavy resource would you like to preload? Depending on the answer you can try following optimizations:

  • If you have complex view hierarchy in your cell, consider refactoring from Autolayout to manual setting frames
  • If your cell should display results of some complex computations or remote images, you would like to have a separate architecture layer for loading these resources and shouldn't do it in cell class anyway. Use caching when necessary.

Upvotes: 2

Related Questions