2015-11-28 7 views
9

UITableViewにテキストとイメージを表示しています。画像が最初にダウンロードされます。画像がダウンロードされる前は画像のサイズがわからないので、最初は固定サイズのUIImageViewを入れました。そして、画像がダウンロードされると、私はUIImageViewのサイズを変更します。イメージのダウンロード後にセルの高さを更新する

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

// Download image 

    dispatch_async(dispatch_get_main_queue(), ^{ 

    // UIImageView resizing 
    }); 
}); 

すべてはcellForRowAtIndexPathで発生します。
私がここで直面している問題は次のとおりです。
1.セルの高さを更新するにはどうすればよいですか? 1つのセルに多くの画像が存在する可能性があることを考慮してください。だから私は1つのダウンロードの上に底のイメージの位置を変更する必要があります。
2. UITableViewbeginUpdatesendUpdatesを使用しようとしましたが、セルの上にスクロールするとユーザーエクスペリエンスが低下します。

これはreloadDataのUIの外観です。ダウンロードする5個のイメージがあります:UI experience after UITableView reloadData

+0

'beginUpdates'と' endUpdates'はこの場合実際には無効です*グループ内ではreloadDataを呼び出さないでください*はドキュメントを参照してください。 – vadian

+0

'reloadData'を試しましたか? –

+0

@HarikrishnanT:はい。 UIの経験が貧弱です。 – Nitish

答えて

11

短い答え

  • は、キャッシュされた細胞
  • トリガAと一度dequeueReusableCellWithIdentifierによって返さUITableViewCellますない仕事を変えるestimatedRowHeight
  • に十分な呼吸スペースを与えます単一セルの再ロードreloadRowsAtIndexPaths
  • コアデータでキャッシュを管理し、NSFetchedResultsControllerボイラープレートコードはすべてのUI作業を行うことができます。詳細は

以下

コードはスクロールしません。リフレッシュされて、細胞がでたり地平線の下であれば

  1. UITableView
  2. 場合をスクロールしません。リフレッシュされるセルが上にあり、UITableViewはスクロールしません。
  3. UITableViewは、セルが見やすいときにのみスクロールし、使用可能なスペースより多くのスペースを必要とします。

UITableViewAutomaticDimensionあなたはそれはあなたが返却しようとしている先の新しいdequeueReusableCellWithIdentifierをトリガするように、セルが古いであることココアタッチを伝える必要がありますハードワーク

をやってみましょう適切な高さのセルセル
テーブルビュー全体またはそのセクションの1つを再ロードすることが短く、インデックスが安定していると仮定すると、変更されたセルのindexPathと.fadeのアニメーションを渡すと-tableView:reloadRows:at:with:が呼び出されます。

コード:

override func viewDidLoad() { 
    super.viewDidLoad() 
    tableView.estimatedRowHeight = 250 // match your tallest cell 
    tableView.rowHeight = UITableViewAutomaticDimension 
} 

使用URLSession。画像が利用可能になると、火災reloadRows:at:with

func loadImage(_ url: URL, indexPath: IndexPath) { 
    let downloadTask:URLSessionDownloadTask = URLSession.shared.downloadTask(with: url, completionHandler: { 
     (location: URL?, response: URLResponse?, error: Error?) -> Void in 
     if let location = location { 
      if let data:Data = try? Data(contentsOf: location) { 
       if let image:UIImage = UIImage(data: data) { 
        self.cachedImages![indexPath.row] = image 
        self.cachedUrls![indexPath.row] = url 
        DispatchQueue.main.async(execute: {() -> Void in 
         self.tableView.beginUpdates() 
         self.tableView.reloadRows(
          at: [indexPath], 
          with: .fade) 
         self.tableView.endUpdates() 
        }) 
       } 
      } 
     } 
    }) 
    downloadTask.resume() 
} 

例:*ウィキペディア*からの画像のランダムなセットをフェッチ

Xcode demo

►はGitHubと、追加でこの解決策を探しますSwift Recipesの詳細。

+0

この場合、heightForRowAtIndexを呼び出す必要がありますか? – Nitish

+0

いいえリンクされたXcodeプロジェクトでは、レガシー高さの計算が必要ないことがわかります。 AutoLayoutは**すべての**作業を行います。それは魔法です。 – SwiftArchitect

+0

私が正しいとすれば、自動レイアウトはテーブルセルのコードに実装されていません。これは、私がセルレイアウトを使ってセルのサブビューを作成する必要があることを示唆していますか?それは必須ではありません。 – Nitish

関連する問題