如何在从带有翠鸟的URL加载图像后调整UIImageView的大小
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在从带有翠鸟的URL加载图像后调整UIImageView的大小相关的知识,希望对你有一定的参考价值。
我想调整任何下载的图像的大小,以便它们保持纵横比,但是它们都与它们呈现的UITableViewCell
一样宽。
我的UIImageView使用contentMode
配置为AspectFit
,我的单元格上有以下锚点:
当前的尝试几乎就在那里:
class AnimatedImageTableViewCell: UITableViewCell {
@IBOutlet weak var gifView: AnimatedImageView!
@IBOutlet weak var imageHeightAnchor: NSLayoutConstraint!
var refreshCell: (() -> Void)?
func render(imageUrl: String) {
guard let url = URL(string: imageUrl) else { return }
gifView.kf.setImage(with: url) { result in
switch result {
case .success(let value):
let ratio = value.image.size.width / value.image.size.height
let newHeight = self.gifView.frame.width / ratio
self.imageHeightAnchor.constant = newHeight
self.refreshCell?()
case .failure(let error):
print(error) // The error happens
}
}
}
}
也:
class HomeViewController: UITableViewController {
let images = [
"https://cdn-images-1.medium.com/max/1600/1*OJxJTJLSyqJ0nMeuswuCSQ.gif",
"https://static1.squarespace.com/static/552a5cc4e4b059a56a050501/565f6b57e4b0d9b44ab87107/566024f5e4b0354e5b79dd24/1449141991793/NYCGifathon12.gif",
"https://media2.giphy.com/avatars/100soft/WahNEDdlGjRZ.gif"
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
tableView.estimatedRowHeight = 200
tableView.rowHeight = UITableView.automaticDimension
tableView.allowsSelection = false
let nib = UINib(nibName: "AnimatedImageTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "cellId")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return images.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let imagePath = images[indexPath.item]
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! AnimatedImageTableViewCell
cell.refreshCell = {
tableView.reloadRows(at: [indexPath], with: .automatic)
}
cell.render(imageUrl: imagePath)
return cell
}
}
但是在某些情况下,细胞太高了。图像呈现全宽,正确的宽高比,图像上方和下方的空间太大。
我也在控制台中出现如下错误:
(
"<NSLayoutConstraint:0x600000329770 Kingfisher.AnimatedImageView:0x7fd339e19330.height == 268.5 (active)>",
"<NSLayoutConstraint:0x60000032a8f0 Kingfisher.AnimatedImageView:0x7fd339e19330.top == UITableViewCellContentView:0x7fd339e1a280.topMargin + 8 (active)>",
"<NSLayoutConstraint:0x60000032a850 UITableViewCellContentView:0x7fd339e1a280.bottomMargin == Kingfisher.AnimatedImageView:0x7fd339e19330.bottom + 8 (active)>",
"<NSLayoutConstraint:0x60000032a7b0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600001908ee0'UIViewLayoutMarginsGuide']-(8)-| (active, names: '|':UITableViewCellContentView:0x7fd339e1a280 )>",
"<NSLayoutConstraint:0x600000323980 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fd339e1a280.height == 450.5 (active)>",
"<NSLayoutConstraint:0x60000032a6c0 'UIView-topMargin-guide-constraint' V:|-(8)-[UILayoutGuide:0x600001908ee0'UIViewLayoutMarginsGuide'] (active, names: '|':UITableViewCellContentView:0x7fd339e1a280 )>"
)
答案
您可以在设置image
属性后尝试调整图像视图的大小。例如:
class ResizableImageView: UIImageView {
override var image: UIImage? {
didSet {
guard let image = image else { return }
let resizeConstraints = [
self.heightAnchor.constraint(equalToConstant: image.size.height),
self.widthAnchor.constraint(equalToConstant: image.size.width)
]
if superview != nil {
addConstraints(resizeConstraints)
}
}
}
}
然后,添加其常规约束,省略heightAnchor
和widthAnchor
,因为这些将在图像添加后立即添加(我建议此时不使用界面构建器):
let imageView = ResizableImageView(frame: .zero)
imageView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imageView)
// These are only illustrative constraints
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
imageView.image = image
这是一个完整且功能齐全的示例:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
downloadImage(
fromURL: URL(string: "https://img.evbuc.com/https%3A%2F%2Fcdn.evbuc.com%2Fimages%2F33105753%2F184176199496%2F1%2Foriginal.jpg?h=200&w=450&rect=0%2C0%2C400%2C200&s=a92a5a03c153d312d682b2dfedd6a6ad")!,
completionHandler: { [weak self] image in
guard let self = self, let image = image else { return }
let imageView = ResizableImageView(frame: .zero)
imageView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(imageView)
imageView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
imageView.image = image
})
}
func downloadImage(fromURL url: URL, completionHandler: @escaping (UIImage?) -> Void) {
let operationQueue = OperationQueue()
operationQueue.addOperation {
guard let data = try? Data(contentsOf: url) else {
OperationQueue.main.addOperation {
completionHandler(nil)
}
return
}
OperationQueue.main.addOperation {
let image = UIImage(data: data)
completionHandler(image)
}
}
}
}
另一答案
尝试使用提供的代码重新创建项目,一切都按预期工作,直到我注意到您的图像视图被限制为单元格内容视图边距。然后它开始抛出那些布局错误,细胞变得不合理地高。所以我的猜测是你需要确保你的图像视图约束与细胞边缘不相关。
还要确保在视图控制器中没有heightForRowAt
覆盖。
要完全摆脱自动布局错误,您可以将底部约束优先级设置为999(blog post,并说明优先级帮助的原因)
以上是关于如何在从带有翠鸟的URL加载图像后调整UIImageView的大小的主要内容,如果未能解决你的问题,请参考以下文章