最近有個需求:根據圖片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()
}
複製代碼