在我的UITableViewCell
中,我有一个UIImageView
,该文件可以异步下载图像(使用Kingfisher库)。它与Instagram非常相似。
我正在使用自动布局,我想使用UITableView.automaticDimension
作为行高。如何设置约束,以使单元格的高度根据图像变高或变短?如果我为UIImageView
的高度设置了初始约束,并在下载图像后对其进行了更改,那么至少有一个元素可以更改其高度以“填充”由{{1}添加(或删除)的空间}。
答案 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")
}
}