将tableViewCell保存在数组中,将UITableViewCell缓存在数组中
Save tableViewCell in an array, Cache UITableViewCell in an array
我正在开发一个 tableView,其中每个单元格都由 AVPlayer 组成,高度为 view.frame.size.height,并且还启用了分页。所以基本上它的工作方式类似于 tiktok 应用程序提要。我遇到的问题是,我必须在调用 cellForRow 时销毁 prepareForReuse 中的 AVPlayer 以显示新视频,否则如果我不销毁它并且用户快速滚动,旧视频会出现一秒钟,如果我销毁每个播放器使用之前的时间然后 AVPlayer 需要一秒钟来加载,并且在两者之间显示黑屏。它有效,但结果并不优雅。
那么有什么方法可以预加载单元格并将它们保存在数组中。就像一个由三个独立单元格组成的数组。我们可以在用户滚动时更改其中的值
例如
[] 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
这听起来更像是集合视图的工作。一旦收到数据,您应该能够通过预取和填充要显示的单元格来实现您想要的平滑加载。
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.
如果这不能满足您的需求,请post您的代码。
更新:
我花了很多时间试图用 tableView 解决这个问题,但未能如愿。我最终制作了一个带有滚动视图的自定义表格视图,它具有问题中提出的类似实现。所以用 scrollview 预加载单元格是可行的。下面提供的代码仅供参考
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)
}
我正在开发一个 tableView,其中每个单元格都由 AVPlayer 组成,高度为 view.frame.size.height,并且还启用了分页。所以基本上它的工作方式类似于 tiktok 应用程序提要。我遇到的问题是,我必须在调用 cellForRow 时销毁 prepareForReuse 中的 AVPlayer 以显示新视频,否则如果我不销毁它并且用户快速滚动,旧视频会出现一秒钟,如果我销毁每个播放器使用之前的时间然后 AVPlayer 需要一秒钟来加载,并且在两者之间显示黑屏。它有效,但结果并不优雅。
那么有什么方法可以预加载单元格并将它们保存在数组中。就像一个由三个独立单元格组成的数组。我们可以在用户滚动时更改其中的值
例如
[] 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
这听起来更像是集合视图的工作。一旦收到数据,您应该能够通过预取和填充要显示的单元格来实现您想要的平滑加载。
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.
如果这不能满足您的需求,请post您的代码。
更新:
我花了很多时间试图用 tableView 解决这个问题,但未能如愿。我最终制作了一个带有滚动视图的自定义表格视图,它具有问题中提出的类似实现。所以用 scrollview 预加载单元格是可行的。下面提供的代码仅供参考
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)
}