Background:

Recently, there is a requirement: depending on whether the image URL link is legal, such as the wrong link, more or less characters, will cause the image loading failure, in this case, you need to hide the UIImageView in the cell.

Let’s look at what the Cell looks like: the red box is the content of the Cell, 1 red dot UIView + 2 UILabel + 1 UIImageView. (Not using UIStackView because there is a red dot that is not easy to align)

Implementation ideas:

  • In the init method of the cell, the default is to set the spacing between the bottom of the dateLabel and the superview 16, while the constraint on the spacing between the bottom of the photoView and the superview 16 is invalid:

    dateLabel.snp.makeConstraints { ... dateLabelBottomConstraint = $0.bottom.equalToSuperview().inset(16).constraint } photoView.snp.makeConstraints { ... photoViewBottomConstraint = $0.bottom.equalToSuperview().inset(16).constraint } photoViewBottomConstraint? .deactivate()Copy the code
  • Set prepareForReuse() to hide the image by default to prevent layout problems with continuous scrolling:

    override func prepareForReuse() { super.prepareForReuse() hideImage() } private func hideImage() { photoView.isHidden = true photoViewBottomConstraint? .deactivate() dateLabelBottomConstraint?.activate() }Copy the code
  • In the cell’s setupPhotoViewImage() method, pass the image URL, and determine whether the URL is valid based on the image loading result. To change dateLabelBottomConstraint, photoViewBottomConstraint, isHidden, thus determine whether image display.

    • First use SDImageCache. Shared. ImageFromCache (forKey:) get SDWebImage cache image, if got, let photoView directly display the image. (sd_cancelCurrentImageLoad() is used here to prevent problems with the request image during cell reuse.)

    • If it does not get the cache, then sd_setImage is used to request the image. In the callback closure after the request is completed, it is determined that if the image is not nil, then it is used to proxy the external View Controller to refresh the current cell. (SDWebImage will automatically cache the image in this step, no need to manually cache again)

    • The above two small steps will avoid the execution of sd_setImage again when the cell is refreshed, and prevent the request image from being refreshed again, resulting in an infinite loop.

    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.sd_cancelCurrentImageLoad() photoView.image = cacheImage showImage() } private func showImage() { photoView.isHidden = false dateLabelBottomConstraint?.deactivate() photoViewBottomConstraint?.activate() }Copy the code