最近有个需求:根据图片url连接是否合法,好比连接贴错了,多了或者少了一些字符等状况,就会致使图片加载失败,遇到这种状况,就须要隐藏掉cell里的UIImageView。缓存
先看看这个Cell长得怎样:红框部分就是这个cell要显示的内容,1个红点UIView + 2个UILabel + 1个UIImageView。(考虑到有个红点不方便对齐,因此没有使用UIStackView)markdown
在cell的init方法里,默认让dateLabel
底部距离父视图16的间距,而让photoView
底部距离父视图16的间距约束失效:闭包
dateLabel.snp.makeConstraints {
...
dateLabelBottomConstraint = $0.bottom.equalToSuperview().inset(16).constraint
}
photoView.snp.makeConstraints {
...
photoViewBottomConstraint = $0.bottom.equalToSuperview().inset(16).constraint
}
photoViewBottomConstraint?.deactivate()
复制代码
在cell的setupPhotoViewImage()
方法里,传递图片URL
,根据加载图片结果,判断URL
是否有效,再改变dateLabelBottomConstraint
、photoViewBottomConstraint
、isHidden
,从而决定图片是否显示。ide
先使用SDImageCache.shared.imageFromCache(forKey:)
去拿SDWebImage缓存的image,若是拿到了,就直接让photoView显示image。布局
若是没拿到缓存,则用sd_setImage
去请求图片,在请求完成的回调闭包里面,判断image若是不为nil,则使用代理让外部view controller刷新当前的cell。(SDWebImage在此步会自动缓存图片,无需手动再缓存)url
上述2小步,就避免了刷新cell的时候又再会去执行sd_setImage
,防止请求图片完成又刷新,致使死循环。spa
func setupPhotoViewImage(inboxMediaURL: URL?) {
guard let cacheImage = SDImageCache.shared.imageFromCache(forKey: inboxMediaURL.absoluteString) else {
photoView.sd_setImage(with: inboxMediaURL) {
[weak self] image, _, _, _ in
guard let self = self, image != nil else { return }
self.delegate?.reloadCellData(self)
}
return
}
photoView.image = cacheImage
showImage()
}
private func showImage() {
photoView.isHidden = false
dateLabelBottomConstraint?.deactivate()
photoViewBottomConstraint?.activate()
}
复制代码
设置prepareForReuse()
,默认中止图片请求,并隐藏图片,防止连续滚动的时候产生布局问题。代理
这里使用了sd_cancelCurrentImageLoad()
是为了防止cell复用的过程当中请求图片发生问题。由于cell的setupPhotoViewImage方法里先去拿cache,没有拿到才会调用sd_setImage
,而 sd_setImage 源码里是有调用了sd_cancelCurrentImageLoad()的,滑动屏幕,cell复用的时候,有些cell有可能不会去调用sd_setImage的,这样就没有中止加载cell里的图片,而这时以前的图片加载完成,就会将图片显示到后续复用了的cell里。code
override func prepareForReuse() {
super.prepareForReuse()
photoView.sd_cancelCurrentImageLoad()
hideImage()
}
private func hideImage() {
photoView.isHidden = true
photoViewBottomConstraint?.deactivate()
dateLabelBottomConstraint?.activate()
}
复制代码