我在
tableview
从上滚动到下时遇到问题。可重复使用的单元格显示旧图像,直到新图像下载完成。
它应该显示我的默认图像占位符,直到下载新图像,下载完成后,然后将 imageView 从图像占位符更改为当前下载的图像。我该怎么办?
更新
表视图控制器:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemTableViewCell") as! ItemTableViewCell
let itemInfo = itemInfos[indexPath.row]
var image1 : UIImage?
var image2 : UIImage?
if let imgUrl1 = itemInfo.imageUrl {
image1 = ItemListViewController.imageCache.object(forKey: imgUrl1 as AnyObject) as? UIImage
}
if let imgUrl2 = itemInfo.cookerProfilePicUrl{
image2 = ItemListViewController.imageCache.object(forKey: imgUrl2 as AnyObject) as? UIImage
}
cell.configureCell(iteminfo: itemInfo, img1 : image1 ,img2 : image2)
return cell
}
西卜:
func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage? ){
if img1 != nil {
imageViewItemPic.image = img1
}
else{
print("hi1")
imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!)
}
if img2 != nil {
imageViewCookerProfilePic.image = img2
}
else{
imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!)
}
labelItemHeading.text = iteminfo.heading
labelItemDescription.text = iteminfo.description
}
更新:
override func awakeFromNib() {
super.awakeFromNib()
self.imageViewItemPic.image = UIImage(named: "resto-placeholder.png")
}
更新:
extension UIImageView {
func setImageFromURL(url: String) {
DispatchQueue.global().async {
let data = NSData.init(contentsOf: NSURL.init(string: url) as! URL)
DispatchQueue.main.async {
let image = UIImage.init(data: data as! Data)
ItemListViewController.imageCache.setObject(image!, forKey: url as AnyObject)
self.image = image
}
}
}
}
由于它是一个可重用的单元格,它确实“重用”了带有旧图像的单元格。然后每次在
cellForRowAtIndexPath
中显示单元格时都需要更新它:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.image=placeholder_image
//then download image
}
您必须为每个
cellForRowAtIndexPath
函数放置一个图像,这意味着在您的代码中您需要编写 else
图像操作条件,并且您需要放置一个占位符图像。因为当您上下滚动时,表格视图单元格会被重复使用,因此,如果您不放置任何新内容,它将保留旧内容,这就是它显示旧/重复内容的原因。
单元初始化时,您可以在
ItemTableViewCell
中设置默认图像
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.image= defaultImage
}
编辑
func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage? ){
if img1 != nil {
imageViewItemPic.image = img1
}
else{
print("hi1")
imageViewItemPic.image = UIImage(named: "resto-placeholder.png")
imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!)
}
if img2 != nil {
imageViewCookerProfilePic.image = img2
}
else{
imageViewItemPic.image = UIImage(named: "resto-placeholder.png")
imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!)
}
labelItemHeading.text = iteminfo.heading
labelItemDescription.text = iteminfo.description
}
正如我遇到同样的问题;在阅读本文之前。我尝试了不同的方法,例如 init 和 awakefromnib。方法是在收到数据后立即调用 func 来更新整个 UI。
另外,请注意我使用
var restData
和 didSet
(这就是为什么它会在从视图控制器接收到数据后立即更新,我不会调用该函数。如果它是从视图控制器调用的函数,您只需将占位符图像最初位于函数开头,然后下载新图像并从视图控制器调用它,例如 cell.updateUI(data: data)
希望你们觉得这很有用。对我来说,我获得了正确的图像,而无需在单元重用上显示预览图像:)
// 表格视图控制器
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : RestCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestCell
//configure the cell to item
cell.restData = items[indexPath.row]
return cell
}
// UITableviewCell
class RestCell: UITableViewCell {
@IBOutlet var img : UIImageView!
@IBOutlet var lbl : UILabel!
// get data and update.
var restData: RestsModel! {
didSet {
// default img early placeholder set. Eliminates showing old pic in cell reuse
self.img.image = UIImage(named: "60x60placeholder.png")
// Update all values func
updateUI()
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Default image placeholder
//self.img.image = UIImage(named: "60x60placeholder.png")
}
// required init.
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
// Color of selected.
let myCustomSelectionColorView = UIView()
myCustomSelectionColorView.backgroundColor = UIColor(red: 234.0/255.0, green: 46.0/255.0, blue: 73.0/255.0, alpha: 0.1) //UIColor(netHex:0xFFFF434)
selectedBackgroundView = myCustomSelectionColorView
}
// updateUI func.
fileprivate func updateUI() {
// download the image
if ( self.restData.image != nil && self.restData.image != "") {
ImageLoader.sharedLoader.imageForUrl(urlString:self.restData.image, completionHandler:{(image: UIImage?, url: String) in
self.img.contentMode = UIViewContentMode.scaleAspectFit
self.img.image = image
})
} else {
self.img.image = UIImage(named: "60x60placeholder.png")
}
self.lbl.text = restData.name as String
}
}
非常简单,不用写太多代码,只需两行即可解决您的问题
cell.thumbnailimage.image = nil
cell.thumbnailimage.setImageWith(imageurl!)
在 xib 文件中将 imageViews 的默认值设置为“nil”。这将确保在加载新图像之前,您的手机上不会有图像。
func configureCell(iteminfo:ItemInfo , img1 : UIImage? , img2 : UIImage? ){
//Set the imageViews to nil to make sure no other picture are set
imageViewItemPic.image = nil
imageViewCookerProfilePic.image = nil
//Check if img1 is not nil
if img1 != nil {
imageViewItemPic.image = img1
} else{
print("hi1")
imageViewItemPic.setImageFromURL(url: iteminfo.imageUrl!)
}
//Check if img2 is not nil
if img2 != nil {
imageViewCookerProfilePic.image = img2
} else{
imageViewCookerProfilePic.setImageFromURL(url: iteminfo.cookerProfilePicUrl!)
}
labelItemHeading.text = iteminfo.heading
labelItemDescription.text = iteminfo.description
}
首先,你可以通过第三方库来克服这个问题。Kingfisher vs.
如果你说我想自己做,我就是这样做的。因为我需要在图像下载中采取额外的安全措施(ssl 固定等)。
在单元格中使用图像下载实际上使用了 imageView 引用。你需要打破这个引用。就我而言,我使用 UITableViewCell 中的prepareForReuse 函数。
首先删除 UIImageView,然后创建一个新的 imageview,将其添加到视图中并再次给出约束。
这里需要注意的一点是,创建cell的时候就好像这个函数在第一次创建的时候不存在一样。然后让这个函数完成它的工作。
open override func prepareForReuse() {
super.prepareForReuse()
imageViewObject?.removeFromSuperview()
imageViewObject = createImageView()
if let imageViewObject = imageViewObject {
addSubview(imageViewObject)
createConstraint()
activateConstraint()
}
}