我試圖更新一個ImageView,它是我的TableViewCell的一部分。每個單元格都有其他國家,對于每個單元格,我想下載國家的國旗并將其顯示在單元格的ImageView中,所以我使用CellForRowAt,準備好單元格的國家并呼叫一個下載國旗影像的函式。但是我不明白,我怎樣才能更新單元格中的ImageView......
。以下是我的代碼:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell"/span>, for: indexPath) as!
//配置單元格...
let stock = stocks[indexPath.row] 。
//>圖片下載
loadCountryImage(country: stock.country)
return cell
}
func loadCountryImage(country: String) {
let url = "https://www.countryflags.io/(country)/shiny/24.png"
guard let imageURL = URL( string: url) else {
print("no URL found"/span>)
回傳。
}
let session = URLSession.share
session.dataTask(with: imageURL) { imageData, _, _ in
let image = UIImage(data: imageData! )
}.恢復()
所以現在圖片被成功下載,但我如何在單元格的imageView中得到它呢?
來自德國的親切問候! Yannik
uj5u.com熱心網友回復:
簡短的答案是將單元格傳遞給loadCountryImage,這樣你就可以從你的資料任務中更新封閉中的單元格影像。 這個更新需要被派發到主佇列中。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell"/span>, for: indexPath) as!
//配置單元格...
let stock = stocks[indexPath.row].
cell.imageView.image = somePlaceholderImage
//影像下載
loadCountryImage(country: stock.country, in: cell)
return cell
}
func loadCountryImage(country: String, in cell:CustomCell) {
let url = "https://www.countryflags.io/(國家)/shiny/24.png"
guard let imageURL = URL(string: url) else {
print("no URL found"/span>)
回傳。
}
let session = URLSession.share
session.dataTask(with: imageURL) { imageData, _, _ in
guard let data = imageData, let image = UIImage( data: data) else {
return
}
DispatchQueue.main.async {
cell.imageView.image = image
}
}.恢復()
}
長的答案是,你應該考慮快取,由于單元格被重復使用,當表格視圖滾動時會發生什么? 你可能會獲取一張已經過期的圖片。 一種方法是將國家存盤在單元格中,并在關閉時檢查它是否仍然是您所期望的,然后再設定影像。
您可以使用UITableviewDatasourcePrefetching和NSCache
。
var imageCache = NSCache<NSString,UIImage>()
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell"/span>, for: indexPath) as!
//配置單元格...
let stock = stocks[indexPath.row].
cell.imageView.image = somePlaceholderImage
cell.country = stock.country
//圖片下載
loadCountryImage(country: stock.country, in: cell)
return cell
}
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath] ) {
for indexPath in indexPaths {
let stock = stocks[indexPath.row]
if self.cache.object(forKey: stock.country) == nil {
self.loadCountryImage(country: stock.country, in: nil)
}
}
}
func loadCountryImage(country。String, in cell:CustomCell?) {
if let image = self.imageCache.object(forKey: country) {
cell?.imageView.image = image
return。
}
let url = "https://www.countryflags.io/(國家)/shiny/24.png"
guard let imageURL = URL(string: url) else {
print("no URL found"/span>)
回傳。
}
let session = URLSession.share
session.dataTask(with: imageURL) { imageData, _, _ in
guard let data = imageData, let image = UIImage( data: data) else {
return
}
DispatchQueue.main.async {
self.imageCache.setObject(image, forKey: country)
if cell?.country== country {
cell?.imageView.image = image
}
}
}.恢復()
}
一個更好的答案可能是看看像SDWebImage或Kingfisher這樣的框架,它們為你做了很多事情。
uj5u.com熱心網友回復:
在現有的解決方案中,你可以將單元格傳遞給你的函式,以便在下載時設定圖片。但這種方法在滾動你的TableView時導致了性能問題,因為單元格被重復使用,你的cellForRowAtIndexPath每次呼叫時,該特定行將在移動螢屏視窗可見,你的下載函式也被觸發了。由于單元格被重復使用,你也遇到了在多個單元格中顯示相同圖片的問題。更好的解決方案是使用SDWebImage形式的cocoaPod。你只需要專注于開發。其余的將由SDWebImage管理,如性能,快取等。 在pod檔案中添加SDWebImage影像
。pod 'SDWebImage'
通過運行pod進行安裝
pod install
在你的viewController中匯入SDWebImage圖片
。import SDWebImage
在cellforRowAt中設定影像
cell.yourImageViewInCell.sd_setImage(with: URL(string: "http://youserver.com/path/to/image.jpg"), placeholderImage。UIImage(named: "placeholder.png")
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/311697.html
標籤:
