图像在 UITableViewCell 中不按顺序显示
Images not show in sequence in UITableViewCell
我正在尝试将 XML enclosure
中的图像显示到 tableViewCell 图像。由于 dequeueReusableCellWithIdentifier
,图像显示但不按顺序显示,因为当我上下滚动 tableViewCell 时,它会更改图像而不按顺序显示 array index
。我尝试了不同的方法,但没有成功'
谁能告诉我如何按顺序显示图像,或者有什么方法可以先下载所有图像然后在单元格图像中显示?
或任何其他快速或简单的方法,而不是使用 dispatch_async
。
谢谢
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
downloadFileFromURL(NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!, completionHandler:{(img) in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.sideImageView.image = img
})
})
return cell
}
UPDATE
现在我尝试了这个
let picURL = self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String
let url = NSURL(string: picURL)
let data = NSData(contentsOfURL: url!)
cell.sideImageView?.image = UIImage(data: data!)
它按顺序显示图像,但很难滚动?
Update2
现在我试过了
var check = true
var imageArrayNsData : [NSData] = []
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
if check == true{
var indeX = 0
for i in posts.valueForKey("enclosure") as! [NSString]{
let picURL = self.posts.objectAtIndex(indeX).valueForKey("enclosure") as! String
let url = NSURL(string: picURL)
let data = NSData(contentsOfURL: url!)
print("download")
imageArrayNsData.append(data!)
indeX++
print(indeX)
}
check = false
}
if check == false{
cell.sideImageView.image = UIImage(data: imageArrayNsData[indexPath.row])
}
return cell
}
此方法只下载一次图片。下载图像后,它会附加到数组中,下次它会显示数组中的图像而无需再次下载。但是这种方法对于滚动来说有点困难。有人知道为什么吗?
问题是 cell
对象在您设置图像时可能已经被重新使用。您需要添加一个检查以确保该单元格仍然代表您想要的内容。这可能很简单:
if tableView.indexPathForCell(cell) == indexPath {
cell.sideImageView.image = img
}
但如果特定项目的索引路径可能在那个时候发生变化(例如,如果用户可以 insert/delete 行),则可能需要更复杂。
您也可以使用像 AlamofireImage 这样的库来为您处理这项工作(以不同的方式)。使用 AlamofireImage,您的代码将如下所示:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
let URL = NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!
cell.sideImageView.af_setImageWithURL(URL)
return cell
}
要异步下载图像并设置为 UITableViewCell 的 UIImageView,您可以向 UIImageView 添加扩展。
extension UIImageView {
func downloadImageFrom(link link:String, contentMode: UIViewContentMode) {
//in my methods, I have a cache to avoid re-downloading my images. Images in cache are identified by its URL
if let _imageData = ImageCache.shareCache.getImageData(link) {
self.image = UIImage(data: _imageData)
return
}
//else, download image
NSURLSession.sharedSession().dataTaskWithURL( NSURL(string:link)!, completionHandler: {
(data, response, error) -> Void in
dispatch_async(dispatch_get_main_queue()) {
self.contentMode = contentMode
if let data = data {
ImageCache.shareCache.cacheImageData(data, imageId: link)
self.image = UIImage(data: data)
}
}
}).resume()
}
}
然后,根据您的回电 cellforrow
,
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
cell.imageView.downloadImageFrom(yourImageUrl)
return cell
我正在尝试将 XML enclosure
中的图像显示到 tableViewCell 图像。由于 dequeueReusableCellWithIdentifier
,图像显示但不按顺序显示,因为当我上下滚动 tableViewCell 时,它会更改图像而不按顺序显示 array index
。我尝试了不同的方法,但没有成功'
谁能告诉我如何按顺序显示图像,或者有什么方法可以先下载所有图像然后在单元格图像中显示?
或任何其他快速或简单的方法,而不是使用 dispatch_async
。
谢谢
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
downloadFileFromURL(NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!, completionHandler:{(img) in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.sideImageView.image = img
})
})
return cell
}
UPDATE
现在我尝试了这个
let picURL = self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String
let url = NSURL(string: picURL)
let data = NSData(contentsOfURL: url!)
cell.sideImageView?.image = UIImage(data: data!)
它按顺序显示图像,但很难滚动?
Update2
现在我试过了
var check = true
var imageArrayNsData : [NSData] = []
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
if check == true{
var indeX = 0
for i in posts.valueForKey("enclosure") as! [NSString]{
let picURL = self.posts.objectAtIndex(indeX).valueForKey("enclosure") as! String
let url = NSURL(string: picURL)
let data = NSData(contentsOfURL: url!)
print("download")
imageArrayNsData.append(data!)
indeX++
print(indeX)
}
check = false
}
if check == false{
cell.sideImageView.image = UIImage(data: imageArrayNsData[indexPath.row])
}
return cell
}
此方法只下载一次图片。下载图像后,它会附加到数组中,下次它会显示数组中的图像而无需再次下载。但是这种方法对于滚动来说有点困难。有人知道为什么吗?
问题是 cell
对象在您设置图像时可能已经被重新使用。您需要添加一个检查以确保该单元格仍然代表您想要的内容。这可能很简单:
if tableView.indexPathForCell(cell) == indexPath {
cell.sideImageView.image = img
}
但如果特定项目的索引路径可能在那个时候发生变化(例如,如果用户可以 insert/delete 行),则可能需要更复杂。
您也可以使用像 AlamofireImage 这样的库来为您处理这项工作(以不同的方式)。使用 AlamofireImage,您的代码将如下所示:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
let URL = NSURL(string: self.posts.objectAtIndex(indexPath.row).valueForKey("enclosure") as! String)!
cell.sideImageView.af_setImageWithURL(URL)
return cell
}
要异步下载图像并设置为 UITableViewCell 的 UIImageView,您可以向 UIImageView 添加扩展。
extension UIImageView {
func downloadImageFrom(link link:String, contentMode: UIViewContentMode) {
//in my methods, I have a cache to avoid re-downloading my images. Images in cache are identified by its URL
if let _imageData = ImageCache.shareCache.getImageData(link) {
self.image = UIImage(data: _imageData)
return
}
//else, download image
NSURLSession.sharedSession().dataTaskWithURL( NSURL(string:link)!, completionHandler: {
(data, response, error) -> Void in
dispatch_async(dispatch_get_main_queue()) {
self.contentMode = contentMode
if let data = data {
ImageCache.shareCache.cacheImageData(data, imageId: link)
self.image = UIImage(data: data)
}
}
}).resume()
}
}
然后,根据您的回电 cellforrow
,
let cell : ImageCell2 = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ImageCell2
cell.titleLabel.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
cell.imageView.downloadImageFrom(yourImageUrl)
return cell