IOS重用机制导致的UITableVIewCell或者UICollectionViewCell显示错误

当我们使用UITableVIew和UICollectionView时都会遇到重用显示问题。IOS系统默认会把标识相同的cell进行重用,你可以在创建cell的代理方法中是用UITableView的- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier方法或者UICollectionView的- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath方法来获取重用栈的cell。

但是,如果你设置的内容和重用的内容没有完全一致就会出现显示错误。下面的例子用于说明:

class SubCategoryCollectionCell: BaseCollectionCell {

    @IBOutlet private weak var imageView: UIImageView!
    @IBOutlet private weak var label: UILabel!
    private var setImage: UIImage?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        label.font = UIFont.font6
        imageView.image = placeholderImage
    }
    
    @objc var image: Any! {
        didSet {
            setImage = nil // 返回初始状态,以便url下载的图片进行设置
            if let img = image as? UIImage {
                imageView.image = img
                setImage = img // 防止之后的url下载的图片覆盖
            } else if let urlString = image as? String {
                if urlString != "" {
                    if let url = URL.init(string: urlString) {
                        imageView.sd_setImage(with: url, placeholderImage: placeholderImage, options: .retryFailed, completed: { [weak self] (image, _, _, _) in
                            guard self != nil else {
                                return
                            }
                            if self!.setImage != nil {
                                self?.imageView.image = self!.setImage
                            } else {
                                self?.imageView.image = image ?? placeholderImage
                                self?.setImage = nil
                            }
                        })
                    }
                } else {
                    imageView.image = placeholderImage
                }
            }
        }
    }
    
    @objc var title: String! {
        didSet {
            label.text = NSLocalizedString(title, comment: "")
        }
    }

}

这个例子中的image是图片数据,它可以是图片、图片的URL字符串。这个例子会出现2种情况:

1. 先设置URL字符串进行异步下载图片的cell被系统重用后,使用静态图片设置。此时,异步下载的图片还没有完成(已经被系统重用了),当异步下载完成后,程序会重新设置图片,导致图片显示不一致。在这种情况下,需要把设置的静态图片保存起来(因为SDWebImage会默认设置图片,所以不能用ImageView的image属性判断),在异步下载完成后,判断存储的静态图片是否存在,存在则重新设置静态图片。

2.先设置静态图片的cell被系统重用后,使用URL字符串进行异步下载图片。这种情况下一般是不用处理的,但是由于第一种情况使用保存的静态图片作为判断条件,如果重新使用URL字符串进行异步下载图片而且没有把之前存储的静态图片清除,在异步下载完成后,程序会把ImageView的Image属性设置为静态图片,导致图片显示错误。所以在每次设置图片资源前和异步下载图片完成后,把存储的静态图片清除,以便异步下载图片能够正确设置。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值