可重复使用的细胞旧图像显示

问题描述 投票:0回答:7

我在

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


            }
        }
    }
}
ios swift uitableview
7个回答
7
投票

由于它是一个可重用的单元格,它确实“重用”了带有旧图像的单元格。然后每次在

cellForRowAtIndexPath
中显示单元格时都需要更新它:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        cell.image=placeholder_image
        //then download image
}

1
投票

您必须为每个

cellForRowAtIndexPath
函数放置一个图像,这意味着在您的代码中您需要编写
else
图像操作条件,并且您需要放置一个占位符图像。因为当您上下滚动时,表格视图单元格会被重复使用,因此,如果您不放置任何新内容,它将保留旧内容,这就是它显示旧/重复内容的原因。


1
投票

单元初始化时,您可以在

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


    }

0
投票

正如我遇到同样的问题;在阅读本文之前。我尝试了不同的方法,例如 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



    }

}

0
投票

非常简单,不用写太多代码,只需两行即可解决您的问题

    cell.thumbnailimage.image = nil
    cell.thumbnailimage.setImageWith(imageurl!)

0
投票

在 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


} 

0
投票

首先,你可以通过第三方库来克服这个问题。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()
        
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.