【问题标题】:Save tableViewCell in an array, Cache UITableViewCell in an array将tableViewCell保存在数组中,将UITableViewCell缓存在数组中
【发布时间】:2020-08-29 04:25:18
【问题描述】:

我正在开发一个 tableView,其中每个单元格由 AVPlayer 组成,并且高度为 view.frame.size.height 并且还启用了分页。所以本质上它的工作方式类似于 tiktok 应用程序提要。我遇到的问题是我必须在 prepareForReuse 中销毁 AVPlayer 以在调用 cellForRow 时显示新视频,否则如果我不销毁它并且用户快速滚动,则较旧的视频会出现一秒钟,如果我销毁每个播放器使用之前的时间,然后 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
  • @RobertCrabtree 是的,但它有利于网络调用,而不是用于单元创建。
  • 确实如此,但如果不查看当前代码,很难说出什么对您有帮助。
  • 这听起来像你的问题,基本上,设置 AVPlayer 需要很长时间,可能(从它的声音)由于网络请求。在您的预取中执行此部分,以便在您的单元格要求它时准备好。另外,我会继续清理您在 prepareForReuse 中的单元格。
  • @DPMitu 已经这样做了,为了进一步解释,我正在播放已下载的手机存储中保存的视频。仍然 avplayer 需要一秒钟才能正确加载并准备好播放。

标签: ios swift uitableview preload prepareforreuse


【解决方案1】:

更新:

我花了很多时间试图用 tableView 解决这个问题,但无法做到。我最终制作了一个带有滚动视图的自定义表格视图,它在问题中提出了类似的实现。所以使用滚动视图来预加载单元格是可行的。下面提供的代码仅供参考

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

【讨论】:

    【解决方案2】:

    这听起来更像是一个集合视图的工作。一旦收到数据,您应该能够通过预取和填充单元格以实现所需的平滑加载。

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

    预取集合视图数据

    在集合视图单元格显示之前加载数据。

    集合视图显示有序的单元格集合 可定制的布局。 UICollectionViewDataSourcePrefetching 协议通过预取 即将到来的集合视图单元格所需的数据。当您启用 预取,集合视图在需要之前请求数据 显示单元格。当显示单元格时,数据是 已经在本地缓存了。

    下图显示了集合视图边界之外的单元格 已预取。

    如果这不能满足您的要求,请发布您的代码。

    【讨论】:

    • 预取也可用于 UITableViews,但我认为您还没有阅读 cmets。我已经在使用预取的东西,但建议用于网络调用而不是单元创建。
    • @HassanKhan,好吧,我已经阅读了关于你原来问题的 cmets 解释了更多。也许看看 UIPageViewController,因为你不能真正加载你在表格视图中建议的方式。我真的需要查看代码来了解如何优化它。
    • @HassanKhan,我从来没有遇到过加载具有复杂布局(包括媒体)的集合视图单元格的问题。我并不是要向您推送集合视图,这正是我用于此类事情的方式,因为表格视图实际上是用于表格的基本布局。此外,通常的做法是在播放视频之前加载封面图片,因为有时这需要时间来加载/设置视频播放器(如您所见)。
    • 我认为您给出的答案与问题无关。因为我尝试了集合视图并没有解决我的问题。无意冒犯。
    • 明白了。您是否要按照 SO 指南上传任何代码? “包含足够的代码以允许其他人重现问题。有关此方面的帮助,请阅读如何创建最小、完整和可验证的示例。” stackoverflow.com/help/how-to-ask
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 2022-10-13
    • 2014-07-14
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多