如何在重新加载 CollectionView 时防止单元格内部的代码来自 运行
How to prevent code from inside a cell from running while CollectionView is being Reloaded
我有一个播放视频的全尺寸单元格,因此屏幕上一次只有 1 个单元格。当我向上和向下滚动时,视频会停止并按预期播放,我没有遇到任何问题。
调用reloadData
时出现问题。
我在用户到达数据源中的倒数第二个项目时进行分页。如果用户位于倒数第二个项目并正在播放视频,则当分页提取数据并调用 reloadData
时,单元格内的当前视频会中断,因为 cellForItem 会为每个新视频保留 运行项目添加了数据源。
我尝试在数据模型中添加一个布尔值 属性 并检查它是否正确,如果是 return 但那没有用
调用 reloadData
后如何防止当前可见 scell 中的代码执行?:
class Video {
var url: URL?
var videoId: String?
var postDate: Double?
var isUserWatchingVideo = false
}
var dataSource = [Video]()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
cell.currentItem = indexPath.item
cell.video = dataSource[indexPath.item]
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
// stop video from playing inside cell
// reset the isUserWatchingVideo property to false
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// when the user gets to the 2nd to last item inside the dataSource start to paginate
handlePagination()
}
func handlePagination() {
// new items are found and called for each new item added
dataSource.append(video)
dataSource.sort(by: { [=11=].postDate ?? 0 > .postDate ?? 0 })
collectionView.reloadData // problem occurs once this runs because cellForItem && didEndDisplayingCell runs for each new item that was added
}
单元格内:
MyCell {
var currentItem: Int?
var video: Video? {
didSet {
guard let video = video else { return }
if video.isUserWatchingVideo { return }
if !video.isUserWatchingVideo {
video.isUserWatchingVideo = true
}
// get url > asset > playerItem > player
cell.player.play()
}
}
}
通过分页加载新项目时,您必须改变方法。您不必在加载新数据时重新加载整个 UICollectionView
,而是必须使用插入项来附加新单元格。
func handlePagination() {
dataSource.append(video)
collectionView.insertItems(at: <#T##[IndexPath]#>)
}
我有一个播放视频的全尺寸单元格,因此屏幕上一次只有 1 个单元格。当我向上和向下滚动时,视频会停止并按预期播放,我没有遇到任何问题。
调用reloadData
时出现问题。
我在用户到达数据源中的倒数第二个项目时进行分页。如果用户位于倒数第二个项目并正在播放视频,则当分页提取数据并调用 reloadData
时,单元格内的当前视频会中断,因为 cellForItem 会为每个新视频保留 运行项目添加了数据源。
我尝试在数据模型中添加一个布尔值 属性 并检查它是否正确,如果是 return 但那没有用
调用 reloadData
后如何防止当前可见 scell 中的代码执行?:
class Video {
var url: URL?
var videoId: String?
var postDate: Double?
var isUserWatchingVideo = false
}
var dataSource = [Video]()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
cell.currentItem = indexPath.item
cell.video = dataSource[indexPath.item]
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
// stop video from playing inside cell
// reset the isUserWatchingVideo property to false
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// when the user gets to the 2nd to last item inside the dataSource start to paginate
handlePagination()
}
func handlePagination() {
// new items are found and called for each new item added
dataSource.append(video)
dataSource.sort(by: { [=11=].postDate ?? 0 > .postDate ?? 0 })
collectionView.reloadData // problem occurs once this runs because cellForItem && didEndDisplayingCell runs for each new item that was added
}
单元格内:
MyCell {
var currentItem: Int?
var video: Video? {
didSet {
guard let video = video else { return }
if video.isUserWatchingVideo { return }
if !video.isUserWatchingVideo {
video.isUserWatchingVideo = true
}
// get url > asset > playerItem > player
cell.player.play()
}
}
}
通过分页加载新项目时,您必须改变方法。您不必在加载新数据时重新加载整个 UICollectionView
,而是必须使用插入项来附加新单元格。
func handlePagination() {
dataSource.append(video)
collectionView.insertItems(at: <#T##[IndexPath]#>)
}