2016-08-03 9 views
1

凍結を避けて迅速にUITableViewからreloadData()を実行する最良の方法は何ですか?フリーズを避けるためにUITableViewデータを再ロードする方法

私はTableViewでViewControllerを持っています。これは、10行のペアのユーザーの一覧を示しています。スクロールが最後の行-1をバックグラウンドで表示すると、アプリケーションは次の10人のユーザーを要求し、残りのユーザーに追加されて、今すぐ20人のユーザーをTableViewに表示します。

委任されたメソッドでこれを実行すると、リロードにより約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. ユーザーはスクロールを停止し、明白な理由で遅れてしまったため、今あなたのアプリに失望しています。私はこれがあなたが「フリーズ」と「不快なナビゲーション」を意味するものだと信じています。

ソリューション:最後の行が表示されるまで

は待って​​はいけません!たとえば、40行から開始し、スクロールが最下部から約15行の距離に達すると、40行がさらにダウンロードされます。そうすれば、ダウンロードがユーザーに完全に滑らかに見えるようにすばやく完了する可能性が高くなります。

本当に欲しいのなら、スクロール速度、行の高さ、サーバーの待ち時間を考慮に入れることができます。しかし、私の経験では、スムーズな「無限スクロール」の経験には本当に必要なものはありません。

あなたと他のレスポンダーは、「テーブル全体のビューを再読み込みする」がこれに責任があると考えるのは間違いです。 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() 
    } 
} 
関連する問題