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。 UITableView
beginUpdates
とendUpdates
を使用してみましたが、セルの一番上までスクロールするため、ユーザーエクスペリエンスが低下します。
これは、reloadDataでのUIの外観です。ダウンロードする画像は5つあります: UITableViewの後のUIエクスペリエンスreloadData
estimatedRowHeight
に十分な呼吸スペースを与えますUITableViewCell
によって返されたdequeueReusableCellWithIdentifier
を変更すると、キャッシュされたセルでは機能しませんreloadRowsAtIndexPaths
を使用して単一セルのリロードをトリガーしますNSFetchedResultsController
ボイラープレートコードですべてのUI作業を実行できるようにします。予期しないスクロールはありません。画像が来たら更新するだけです:
UITableView
notスクロールしますUITableView
はnotになりますスクロールUITableView
は、セルがはっきりと見える場合にのみスクロールし、およびは使用可能なスペースよりも多くのスペースを必要とします。UITableViewAutomaticDimension
に大変な仕事をさせましょう
セルがstaleであることをCocoa Touchに通知して、newdequeueReusableCellWithIdentifier
をトリガーする必要があります。 、適切な高さのセルを返します。
テーブルビュー全体またはそのセクションの1つを再読み込みし、インデックスが安定していると仮定して、-tableView:reloadRows:at:with:
を呼び出し、変更したばかりのセルのindexPathを渡し、.fade
アニメーション。
コード:
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 // Save into the cache
DispatchQueue.main.async(execute: { () -> Void in
self.tableView.beginUpdates()
self.tableView.reloadRows(
at: [indexPath],
with: .fade)
self.tableView.endUpdates()
})
}
}
}
})
downloadTask.resume()
}
キャッシュに入ると、cellForRow
はUIスレッドからキャッシュに読み込むだけです。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "id") as! CustomCell
cell.imageView.image = cachedImages[indexPath.row] // Read from the cache
return cell
}
例:*ウィキペディア*からランダムな画像のセットをフェッチします
►このソリューションは GitHub で、詳細は Swift Recipes で見つけてください。