Search code examples
iosswiftuitableviewpreloadprepareforreuse

Save tableViewCell in an array, Cache UITableViewCell in an array


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

Solution

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