在UITableView中加载图像url swift 2的最佳方法 [英] Best way to load image url swift 2 in UITableView
问题描述
我想创建一个带有swift 2的图像链接列表的A Ui TableView:
I want to create A Ui TableView with a list of image link with swift 2:
例如: var images = [link1 ,link2,...,linkN]
我创建了一个自定义单元格来显示图像:
I create a custom cell to display the image :
let cell = tableView.dequeueReusableCellWithIdentifier(CurrentFormTableView.CellIdentifiers.ImageCell, forIndexPath: indexPath) as! ImageCell
cell.urlImageView.tag = indexPath.row
cell.displayImage(images[index.row])
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
在这里,我有自定义单元格来加载我的图像:
And here I have my custom cell to load my image :
import UIKit
class ImageCell: UITableViewCell {
@IBOutlet weak var urlImageView: UIImageView!
@IBOutlet weak var loadingStatus: UIActivityIndicatorView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func loadImageFromUrl(url: String, view: UIImageView){
if view.image == nil {
self.startLoading()
// Create Url from string
let url = NSURL(string: url)!
// Download task:
// - sharedSession = global NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage objects.
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
// if responseData is not null...
if let data = responseData{
// execute in UI thread
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.stopLoading()
view.image = UIImage(data: data)
})
}
}
// Run task
task.resume()
}
}
func displayImage(imageUrl: String){
imageView?.image = nil
if imageUrl != nil && imageUrl != "" {
print(imageUrl)
loadImageFromUrl(imageUrl,view: urlImageView)
} else {
loadingStatus.hidden = true
}
}
func startLoading(){
loadingStatus.hidden = false
loadingStatus.startAnimating()
}
func stopLoading(){
loadingStatus.hidden = true
loadingStatus.stopAnimating()
}
}
问题在于,她对图像的加载时间是正确的,有时,一个或多个图像覆盖另一个因此我有多个相同的图像而不是看到我所有不同的形象。怎么可能?我的错误在哪里?
The problem is that, she times the images are loading correctly, and sometimes, one image or more "override the other" so I have multiple identical images instead of see all my different images. How it is possible ? Where is my mistake ?
推荐答案
你没有实现细胞的重复使用,这意味着imageView的一个细胞的图像将会与重新使用的另一个相同,直到新图像加载完毕。
You're not implementing the reuse of the cells, meaning that the imageView's image of one cell will be the same as another that it was reused from, until the new image has loaded.
为了防止这种情况,请实现 -prepareForReuse:method
:
To prevent this, implement the -prepareForReuse: method
:
override func prepareForReuse() {
super.prepareForReuse()
urlImageView.image = nil
// cancel loading
}
此外,你不应该在视图层中执行任何与网络相关的代码,它应该在视图控制器中完成。如果已经为特定单元格下载了图像,并且改变了其他视图的状态,这将允许您实现缓存机制。
Furthermore, you shouldn't be doing any network-related code in the view layer, it should be done in the view controller. This will allow you to implement caching mechanisms if the image has already been downloaded for a specific cell, as well as alter the state of other views.
即。在您的视图控制器中:
i.e. In your view controller:
var cachedImages = [String: UIImage]()
func cellForRow...() {
let imageURL = imageURLs[indexPath.row]
if let image = cachedImages[imageURL] {
cell.urlImageView.image = cachedImages[imageURL]
}
else {
downloadImage(indexPath, { image in
if let image = image {
cachedImages[imageURL] = image
cell.urlImageView.image = image
}
})
}
}
func downloadImage(indexPath: NSIndexPath, callback: () -> (UIImage?)) {
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
// if responseData is not null...
if let data = responseData {
// execute in UI thread
dispatch_async(dispatch_get_main_queue(), {
callback(UIImage(data: data))
})
}
else {
dispatch_async(dispatch_get_main_queue(), {
callback(nil)
})
}
}
// Run task
task.resume()
}
这篇关于在UITableView中加载图像url swift 2的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!