Save tableViewCell in an array, Cache UITableViewCell in an array

229 Views Asked by At

I am developing a tableView where each cell consists of AVPlayer and has the height of view.frame.size.height and paging is also enabled. so essentially it will work similar to tiktok application feed. The problem I am having is that I've to destroy AVPlayer in prepareForReuse to show new video when a cellForRow is called otherwise if I don't destroy it and user scroll fast, the older video appear for a second and if I destroy player each time before using then AVPlayer takes a second to load and in between show black screen. It works but the result is not elegant.

So is there any way I can preload cells and save them in an array. Like an array which will consist of three independent cells. and we can change the value in them when a user scroll

For example

[] represents cell on screen

0 [1] 2

array[1] would always be the cell on screen 
array[0] previous
array[2] next

if user scroll down then
array[0] = array[1]
array[1] = array[2] 
array[2] = create next one (proactively)

if user scroll up then
let array1 = array[1]
array[1] = array[0]
array[0] = array1
array[2] = create new one
2

There are 2 best solutions below

0
Hassan Khan On BEST ANSWER

Update:

I spent a lot of time trying to solve this problem with tableView but was unable to do so. I ended up making a custom tableview with scrollview which have the similar implementation asked in the question. So it is doable with scrollview to preload cells. Code provided below is just for reference

  func scrollViewDidScroll(_ scrollView: UIScrollView) {
    //Condition for first cell
    if currentIndex == 0 && (scrollView.contentOffset.y > view.frame.minY) {
        //pageIndex will only be one if the user completly scrolls the page, if he scroll half a returns it will remain 0
        if pageIndex == 1 {
            //so if the user completely scroll to page 1 the change the previous index to 0
            //new current index will be 1
            //call scrollForward which will prepare the cell for index 2
            previousIndex = currentIndex
            currentIndex = Int(pageIndex)
            if shouldCallScrollMethods {
                scrollForward()
            }

            guard let currentCell = getCellOnScreen() else { return }
            currentCell.refreshBottomBarView()
        }
    //Condition for rest of the cells
    } else {
        //this condition checks if the user completly scroll to new page or just drag the scrollview a bit gets to old position
        if (pageIndex != currentIndex) {
            //Update the previous and current to new values
            previousIndex = currentIndex
            currentIndex = Int(pageIndex)
            //Checks if the user is scroll down the calls scrollForwad else scrollBackward
            if shouldCallScrollMethods {
                if currentIndex > previousIndex {
                   scrollForward()
                } else {
                   scrollBackward()
                }
            }
            guard let currentCell = getCellOnScreen() else { return }
            currentCell.refreshBottomBarView()
        }
    }
}

private func scrollForward() {
    //print("scrollForward")
    addCell(at: currentIndex + 1, url: getPlayerItem(index: currentIndex + 1))
    removeCell(at: currentIndex - 2)

}

private func scrollBackward() {
    //Condition to check if the element is not at 0
    //print("scrollBackward")
    addCell(at: currentIndex - 1, url: getPlayerItem(index: currentIndex - 1))
    removeCell(at: currentIndex + 2)
}
7
elliott-io On

This sounds more like a job for a collection view. You should be able to achieve the smooth loading you want by prefetching and populating the cell for display once the data is received.

https://developer.apple.com/documentation/uikit/uicollectionviewdatasourceprefetching/prefetching_collection_view_data

Prefetching Collection View Data

Load data for collection view cells before they are displayed.

A collection view displays an ordered collection of cells in customizable layouts. The UICollectionViewDataSourcePrefetching protocol helps provide a smoother user experience by prefetching the data necessary for upcoming collection view cells. When you enable prefetching, the collection view requests the data before it needs to display the cell. When it’s time to display the cell, the data is already locally cached.

The image below shows cells outside the bounds of the collection view that have been prefetched.

If this doesn't do what you are looking for, please post your code.