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