Swift:在UITableViewCell中异步加载图像-自动布局问题

时间:2019-06-06 09:27:26

标签: ios swift uitableview autolayout

在我的UITableViewCell中,我有一个UIImageView,该文件可以异步下载图像(使用Kingfisher库)。它与Instagram非常相似。

enter image description here

我正在使用自动布局,我想使用UITableView.automaticDimension作为行高。如何设置约束,以使单元格的高度根据图像变高或变短?如果我为UIImageView的高度设置了初始约束,并在下载图像后对其进行了更改,那么至少有一个元素可以更改其高度以“填充”由{{1}添加(或删除)的空间}。

2 个答案:

答案 0 :(得分:1)

使用图像的实际尺寸和每个设备的屏幕尺寸计算长宽比保留的高度,并更新UITableViewCell上的UIImageView高度约束。

只需在tableView(_:cellForRowAt :)上调用feedCell.configure(with:FeedImage)

// FeedImage data will be load from your API, in the best practices, you should get actual sizes of the image from your API

struct FeedImage {
    var url: String = ""
    var width: CGFloat = 0.0
    var height: CGFloat = 0.0
}

class FeedCell: UITableViewCell {

    @IBOutlet weak var feedImageView: UIImageView!
    @IBOutlet weak var feedImageViewHeightConstraint: NSLayoutConstraint!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    func configure(with feedImage: FeedImage) {

        feedImageViewHeightConstraint.constant = getAspectRatioPreservedHeight(actualWidth: feedImage.width, actualHeight: feedImage.height)

        feedImageView.loadImage(with: feedImage.url) // Asynchronous image downloading and setting, you can use any library such as SDWebImage, AlamofireImage, Kingfisher or your custom asynchronous image downloader

    }

    // Calculate the aspect ratio preserved height using with actual size of the images and device screen sizes.
    private func getAspectRatioPreservedHeight(actualWidth: CGFloat, actualHeight: CGFloat) -> CGFloat {

        let WIDTH = UIScreen.main.bounds.width
        let HEIGHT = UIScreen.main.bounds.height

        if (actualWidth == 0) { return CGFloat(400.0) }

        let newComputedHeight = (WIDTH*actualHeight)/actualWidth

        if newComputedHeight > (HEIGHT * 0.6) {
            return (HEIGHT * 0.6)
        }

        return newComputedHeight
    }

}

答案 1 :(得分:0)

您必须按比例裁剪图像,然后保存到KingFisher缓存。

let cached = ImageCache.default.imageCachedType(forKey: url)
        if cached != .none {
            getImageFromCache(key: url) { [weak self] (cachedImage) in
                self?.image = cachedImage
                self?.completionHandler?(cachedImage)
            }
        }
        else {
            getImageFromServer(key: url) { [weak self] (cahcedImage) in
                self?.image = cahcedImage
                ImageCache.default.store(cahcedImage, forKey: self!.url)
                self?.completionHandler?(cahcedImage)
            }
        }





 func getImageFromCache(key:String,complition:@escaping (UIImage)->()) {
        ImageCache.default.retrieveImage(forKey: url, options: nil) { [weak self] (image, cachetype) in

            guard let cachedImage = image , let opCancelled = self?.isCancelled , opCancelled == false  else {
                return
            }
            complition(cachedImage)
        }
    }

    func getImageFromServer(key:String,complition:@escaping (UIImage)->()) {
        if let imageUrl = URL(string: key) {
            KingfisherManager.shared.retrieveImage(with: imageUrl, options: nil, progressBlock: nil) { [weak self] (image, error, cachetype, _ ) in
                if error == nil {
                    guard let cachedImage = image , let opCancelled = self?.isCancelled , opCancelled == false  else {
                        return
                    }


                        let finalheight = (UIScreen.main.bounds.width * CGFloat(cachedImage.size.height)) / CGFloat(cachedImage.size.width)
                        let newImage = cachedImage.resize(targetSize: CGSize(width: UIScreen.main.bounds.width, height: finalheight))
                        complition(newImage)

                }
                else {
                    print("Error ###### == Errror While Downloading Image")
                }
            }
        }
        else {
            print("Error ###### == can't create Url of String")
        }
    }