簡體   English   中英

預加載UITableView單元格

[英]Preloading UITableView cells

我有一個UITableView,它從數據庫中檢索一些預取相對昂貴的數據。 為了解決這個問題,我使用了LazyTableImages示例代碼中的設計思想,在使用[UITableView visibleCells]滾動結束時獲取可見行的數據。

這在性能方面效果很好,但它有兩個我想解決的交互問題:

  1. 在滾動完全停止(即scrollViewDidEndDecelerating )之前,不會加載數據。 因此,如果我在列表中緩慢滾動,我必須停止滾動以將數據加載到那些可見單元格中。 理想情況下,如果滾動速度很慢,我會將數據加載到單元格中。
  2. 我想預取一些或兩個表格單元格數據,這些數據只是在屏幕上,因為它們正在滾動到它們。

有一種優雅的方式來實現這一目標嗎? 我覺得我可能會錯過這個問題的常見設計模式。

我認為您可以在滾動開始時開始加載數據,這樣您就不必等待滾動結束。 您可以使用以下兩種方法之一:

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{}

而且你總是可以得到可見單元格的索引,所以我認為你應該能夠加載幾個數據而不僅僅是可見單元格。

如果你按原樣使用LazyTableImages代碼,這是正常的。 延遲加載直到滾動結束。 在我的測試應用程序(一個簡單的類似於Instagram的流)中,我使用了一種不同的方法:基本上我將單元格子類化,從單元格本身開始下載,使用單元格作為我的下載管理器的委托,然后更新單元格的UI下載完成后

詳細地

  • 我在cellForRowAtIndexPath方法中開始下載(如果視圖滾動,則LazyTableImages推遲下載,我不會因為我可以在滾動時加載)調用我的單元格的“startDownload”方法。
  • 我的單元子類被設置為我的下載管理器的委托,當下載完成時,單元格將使用真實圖像更改占位符(這是在自定義的“downloadManagerDidFinishDownloadForImage:(UIImage *)image”委托方法中完成的,在細胞亞類)
  • 在我的單元子類中,我重寫了prepareForReuse方法。 在這里,如果要重復使用單元格,我可以選擇停止下載。 在我的情況下,我只是取消設置委托並繼續下載,因為我有一些使用核心數據進行的圖像緩存,我希望緩存繼續。

而且,你必須要處理兩件事:

  • 您的下載管理器需要在后台線程中工作
  • 一定要在主線程中更新您的單元格UI。 您可以使用

dispatch_async(dispatch_get_main_queue(), ^{
    //update here your cell UI
});

在委托方法中(如果您的下載管理器調用該方法,它肯定在后台線程中調用,因此您必須“使用調度”在主線程中“移動”。

如果你想要你可以看看我的例子,但它是“按原樣”(它是一個測試應用程序,有很多意大利面條代碼和與你的問題無關的東西;-)

http://www.lombax.it/documents/InstaXplore.zip

在我的例子中,你必須看看:

  • BrowseCell < - 細胞亞類
  • BrowsePhotoViewController < - tableviewcontroller

其他的東西與核心數據存儲和Instagram有關,但基本上

  • 在cellForRowAtIndexPath中我創建一個新單元格(或重用前一個單元格)並傳遞一個InstaImage項目(我的自定義圖像)
  • InstaImage檢查是否存在緩存副本,如果不存在,則開始下載,然后提醒單元格

你有一個清晰的緩存按鈕,一次又一次地嘗試:-)

// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;



(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
        //fetch data for visible rows
    }
}

如果我沒有誤解你的問題,我想你可以用它。 您在顯示某個單元格時加載。

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

}

懶惰圖像邏輯是一個很好的解決方案,我曾經在我的tableviews中使用,但最近我一直在為UITableViews實現不同的解決方案。 第一個是實施NSOperation隊列,就像Apple在WWWDC中提供的視頻一樣https://developer.apple.com/videos/wwdc/2012/?include=211#211

或者您可以嘗試創建一個無限滾動,當您到達某個uitableviewcell時,您將加載一個包含更多數據的新“頁面”,如果您需要這個解決方案的幫助,請告訴我們!

希望這可以幫助!

最好的祝福,

喬治。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM