[英]Swift: loading image asynchronously in UITableViewCell - Autolayout issue
In my UITableViewCell
I have a UIImageView
that download image asynchronously (with Kingfisher library). 在我的
UITableViewCell
我有一个UIImageView
,可以异步下载图像(使用Kingfisher库)。 It's very similar to Instagram. 它与Instagram非常相似。
I'm using autolayout and I want to use UITableView.automaticDimension
for row height. 我正在使用自动布局,我想使用
UITableView.automaticDimension
作为行高。 How should I set constraints so that the height of the cell becomes taller or shorter according to the image? 如何设置约束,以使单元格的高度根据图像变高或变短? If I set an initial constraint for the
UIImageView
height and change it once I download the image, I have at leat one element that changes its height to "fill" the space added (or removed) by the UIImageView
. 如果我为
UIImageView
高度设置了一个初始约束,并在下载图像后对其进行了更改,那么我将保留一个更改其高度以“填充”由UIImageView
添加(或删除)的空间的元素。
Calculate the aspect ratio preserved height using with actual size of the images and device screen sizes for each one, and update UIImageView height constraint on the UITableViewCell. 使用图像的实际大小和每个设备的设备屏幕大小计算长宽比保留的高度,并更新UITableViewCell上的UIImageView高度约束。
Just call feedCell.configure(with: FeedImage) on the tableView(_:cellForRowAt:) 只需在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
}
}
you have to Crop Image Propotionally and than save to KingFisher Cache. 您必须按比例裁剪图像,然后保存到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")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.