Swift: асинхронная загрузка изображения в UITableViewCell - проблема с авторазмещением - PullRequest
0 голосов
/ 06 июня 2019

В моем UITableViewCell у меня есть UIImageView, который загружает изображение асинхронно (с библиотекой Kingfisher).Это очень похоже на Instagram.

enter image description here

Я использую автоматическое расположение и хочу использовать UITableView.automaticDimension для высоты строки.Как я должен установить ограничения, чтобы высота ячейки становилась выше или короче в зависимости от изображения?Если я устанавливаю начальное ограничение для высоты UIImageView и изменяю его после загрузки изображения, у меня есть один элемент, который меняет свою высоту, чтобы «заполнить» пространство, добавленное (или удаленное) с помощью UIImageView.

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Рассчитайте соотношение сторон для сохранения высоты с использованием фактического размера изображений и размеров экрана устройства для каждого из них и обновите ограничение высоты UIImageView для UITableViewCell.

Просто вызовите feedCell.configure (with: FeedImage) для tableView (_: cellForRowAt:)

// 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
    }

}
0 голосов
/ 07 июня 2019

Вы должны Crop Image Propotionally, а затем сохранить в KingFisher Cache.

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")
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...