In my UITableViewCell
I have a UIImageView
that download image asynchronously (with Kingfisher library). It's very similar to Instagram.
I'm using autolayout and I want to use UITableView.automaticDimension
for row height. 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
.
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.
Just call feedCell.configure(with: FeedImage) on the 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
}
}
you have to Crop Image Propotionally and than save to 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")
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.