2016-08-03 82 views
1

一些有經驗的人可以告訴我什麼是在快速避免凍結的情況下從UITableView執行reloadData()的最佳方法?如何重新加載UITableView數據,避免凍結

我有一個ViewController與一個TableView,這顯示了用戶列表中的10行對。當滾動顯示最後一行時--1,在後臺,應用程序請求下一個10個用戶,然後將它們添加到其他用戶,以便在TableView中顯示20個用戶。

當使用委託方法執行此操作時,重新加載會導致大約1〜2秒的凍結並導致不舒服。

任何想法解決這個?

+0

相反重裝你可以手動添加的細胞,當你接受他們的。 – eMKa

+0

您開始提供的數據是如何提供的? (如果是網絡連接,您通常希望在後臺請求數據,然後在收到後在主線程上重新加載數據。) –

回答

6

當新數據到來時,您不需要重新加載整個tableView。你只需要相應地插入新的行。這不會造成任何滯後/凍結。

func didFinishLoadNewUsers(newUsers: [User]) { 
    tableView.beginUpdates() 
    //array of index paths for new rows at the bottom 
    var indexPaths = [NSIndexPath]() 
    for row in (currentUsers.count..<(currentUsers.count + newUsers.count)) { 
     indexPaths.append(NSIndexPath(forRow: row, inSection: 0)) 
    } 
    //update old data 
    currentUsers.appendContentsOf(newUsers) 
    //insert new rows to tableView 
    tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic) 
    tableView.endUpdates() 
    } 
+0

如果此答案適用於您,請將其標記爲「已接受」。 –

+0

嗨。是的,這對我很有用,它非常有用。非常感謝 – amelian

0

如果我正確理解你的問題,你的症狀是這樣的:

  1. 用戶滾動至底部。
  2. 滾動停止(因爲達到底部)。
  3. 您的控制器注意到用戶到達底部並開始下載更多行。
  4. 新行完成下載時會有一個醜陋的延遲。
  5. 您插入新行,現在用戶可以恢復滾動。
  6. 用戶現在對你的應用感到失望,因爲它停止了滾動,並且沒有明顯的原因延遲。我相信這就是你所說的「凍結」和「不舒服的導航」。

解決方案:

不要等到顯示最後一排!例如:從40行開始,下載40行時,滾動距離底部約15行。這樣,下載將很快完成,很有可能使用戶看起來非常順暢。

如果你想變得很花哨,你可以考慮滾動速度,行高和服務器延遲。但以我的經驗來看,沒有任何一項對於平滑的「無限滾動」體驗來說是非常必要的。

在所有應有的尊重下,您和其他回覆者認爲「重新加載整個表格視圖」對此負責。 UITableView.reloadData()實際上是無縫的(如果用戶還沒有到達底部)。

試試這個:

var shouldDownloadMoreRows : Bool { 
    get { 
     // This should return false if the server tells us there are no more rows. 
     // For example, if our last request for 40 got less than 40 rows, then we 
     // can probably assume there are no more. 
     // It should also return false if a request is currently in progress, or a 
     // request failed within the last 0.5 seconds or so, or if the controller 
     // is quitting (about to animate away). 
     return ... 
    } 
} 

func downloadMoreRows() { 
    ... 

    // After the download finishes 
    didFinishDownloadingMoreRows() 
} 

func didFinishDownloadingMoreRows() { 
    // This will be smooth. It will not disrupt scrolling or cause any freezing or lag. 
    self.tableView.reloadData() 
} 

func tableView(tableView: UITableView, 
       willDisplayCell cell: UITableViewCell, 
       forRowAtIndexPath indexPath: NSIndexPath) { 
    let numRowsInSection = tableView.numberOfRowsInSection(indexPath.section) 
    if self.shouldDownloadMoreRows && indexPath.row + 15 >= numRowsInSection { 
     self.downloadMoreRows() 
    } 
}