UITableViewCell 子类化单元格中的错误图像或旧图像错误 [英] UITableViewCell subclass wrong image in cell or old image bug

查看:25
本文介绍了UITableViewCell 子类化单元格中的错误图像或旧图像错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

伙计们,我曾经有 Massive View Controller 问题,特别是在使用 UITableView 时,现在我将旧应用程序更改为更加模态.之前,我曾经在 cellForRowAt indexPath 处设置整个单元格.设置标签、下载图片等

So guys, well I used to have the Massive View Controller problem, specially when using UITableView, now im changing an old app to be more modal. Before, I used to set the whole cell at cellForRowAt indexPath. set labels, download image etc.

现在我正在使用正确的方法设置 UITableViewCell 子类.但我遇到的问题之一是,在更新/下载新图片时重用留下旧图片的单元格,我想我已经解决了,但我也注意到它恰好将错误的图像放在错误的单元格中,然后在快速滚动左右时更新到正确的...

Now I'm using the correct approach to set at the UITableViewCell subclass. but I'm having the problem of either, reuse cells where leaving the old pic while updating/downloading the new one, which I think I fixed, but I also noted it happens to be kinda putting the wrong image in the wrong cell and then updating to the correct one when doing a fast scroll or so...

在我可以做这样的事情之前,以确保图像在正确的单元格中更新.那是在像这样从视图控制器设置整个单元格时...

Before I could do something like this to make sure the image is updated in the correct cell. that's when setting the whole cell from the view controller like this...

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Identifier")

    cell.title = "Cool title"

    imageLoader.obtainImageWithPath(imagePath: viewModel.image) { (image) in
        // Before assigning the image, check whether the current cell is visible for ensuring that it's right cell
        if let updateCell = tableView.cellForRow(at: indexPath) {
            updateCell.imageView.image = image
        }
    }    
    return cell
}

现在我几乎只在 viewcontroller...

Now I pretty much only have this at the viewcontroller...

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell : RestCell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestCell

    // Pass data to Cell :) clean the mess at the View Controller ;)
    cell.restData = items[indexPath.row]

    return cell
}

我有这个 UITableViewCell 子类.

And the UITableViewCell subclass I have this.

class RestCell: UITableViewCell {

    @IBOutlet var img : UIImageView!
    @IBOutlet var lbl : UILabel!
    @IBOutlet var lbl_tipocomida: UILabel!
    @IBOutlet var lbl_provincia: UILabel!
    @IBOutlet var img_orderonline: UIImageView!
    @IBOutlet var img_open: UIImageView!
    @IBOutlet var imgalldelivery: UIImageView!
    @IBOutlet var img_reservasonline: UIImageView!

    // 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   
    }   

    fileprivate func updateUI() {

        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
        self.lbl_provincia.text = restData.provincia as String
        self.lbl_tipocomida.text = restData.tipocomida as String

        // check if has alldelivery enabled, show Alldelivery logo
        if( self.restData.reservaonline == "1") {
            self.img_reservasonline.isHidden = false
            self.img_reservasonline.image = UIImage(named: "icon_reserva_on")

        } else {
            self.img_reservasonline.isHidden = true
            self.img_reservasonline.image = UIImage(named: "icon_reserva_off")
        }

        // check if has orderonline, show ordeonline text
        if ( self.restData.orderonline == "1") {
            self.img_orderonline.isHidden = false
        } else {

            self.img_orderonline.isHidden = true
        }

        // check if has schedule, display if open or close

        if (self.restData.hasSchedule == true) {

            if ( self.restData.openNow == true) {
                self.img_open.image = UIImage(named:"icon_open")
            }  else {
                self.img_open.image = UIImage(named:"icon_close")
            }

            self.img_open.isHidden = false
        } else {

            self.img_open.isHidden = true
        }

    }

}

我从 UITableViewVCell 子类调用图像下载并将其设置在那里.如何确保图像仅设置为正确的单元格???

I'm calling the download on the image from the UITableViewVCell subclass and setting it there. How can I make sure the image is being set to the correct Cell only???

推荐答案

我建议您使用 3rd 方库加载带有 url 的图像,例如 Kingfisher.它将为您处理缓存和取消加载.

I recommend you to use 3rd party library to load image with url such as Kingfisher. It will handle caching and cancel loading for you.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let data = dataSource[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "Identifier") as! ACell
    cell.update(data)
    return cell
}

单元格看起来像这样.

import Kingfisher
class ACell: UITableViewCell {
    @IBOutlet fileprivate weak var backgroundImageView: UIImageView!

    fileprivate func reset() {
        backgroundImageView.image = nil
    }

    func update(_ data: ATypeOfData) {
        reset()
        let resource = ImageResource(downloadURL: url)
        backgroundImageView.kf.setImage(with: resource)
    }
}

你失败的原因是你误解了重用单元格.

The reason you are failing is you misunderstood reusing cell.

let updateCell = tableView.cellForRow(at: indexPath)

updateCell 可以是与您要使用的单元格不同的单元格.它可以只是一个重复使用的随机单元.如果你真的想跟踪一个单元格,你需要设置一个属性并检查 cellForRowAt 中的属性是否与图像加载闭包中的属性相同.我真的建议你使用我附上的模式.

The updateCell can be a different cell with a cell which you want to use. It can be just a reused random cell. If you really want to track a cell, you need to set a property and check the property in cellForRowAt is same as the property in your image loading closure. I really recommend you to use the pattern I attached.

这篇关于UITableViewCell 子类化单元格中的错误图像或旧图像错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆