带有 UIImage 的 Swift 5 表格视图单元格显得非常高并且图像非常缩放

Swift 5 table view cell with UIImage appears very tall and image extremely zoomed(带有 UIImage 的 Swift 5 表格视图单元格显得非常高并且图像非常缩放)

本文介绍了带有 UIImage 的 Swift 5 表格视图单元格显得非常高并且图像非常缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个聊天应用程序,所以行的高度会有所不同.我正在使用单独的单元格作为纯 txt 味精和带有图像(可能还有文本)的味精.我允许用户从手机中选择图像.我在一个单独的 VC 中显示该图像,如果他选择并发送它,他可以在其中输入文本.我有一个 msg 模型,这意味着我在 base64 和图像格式之间进行转换.我试图将我的单元类简化到最大以理解以下问题:图像视图中的图像看起来缩放超出了正常手机缩放所允许的范围;牢房的高度是巨大的.在我需要使用的单元类上,我有更多的项目和约束,但这里感兴趣的基本逻辑如下:

Im working on a chat app, so the height of the rows varies. I am using separate cells for plain txt msg and msg with image (and maybe text). I allow the user to select an image from the phone. I display that image in a separate VC where he can enter text if he chooses and send it. I have a model for the msg which means I do conversion between base64 and image formats. I have tried to simplify to the max my cell class to understand the following problem: the image inside the image view appears zoomed beyond what the normal phone zoom would allow; and the height of the cell is immense. On the cell class that I need to use I have more items and constraints but the basic logic of interest here is below:

    fileprivate func configureMsgsTable() {
    tableView.contentInsetAdjustmentBehavior = .automatic
    tableView.backgroundColor = .clear
    tableView.keyboardDismissMode = .interactive
    tableView.separatorStyle = .none
    tableView.showsVerticalScrollIndicator = false
    tableView.rowHeight = UITableView.automaticDimension
    tableView.estimatedRowHeight = 100
    tableView.sectionFooterHeight = 0.0
}

这些是我用于编码/解码的函数:

these are the functions I use for encoding/decoding:

fileprivate func convertImageToBase64String (img: UIImage) -> String {
    let imageData:NSData = img.jpegData(compressionQuality: 0.50)! as NSData
    let imgString = imageData.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters)
    return imgString
}
fileprivate func convertBase64StringToImage (imageBase64String:String) -> UIImage {
    let imageData = Data.init(base64Encoded: imageBase64String, options: Data.Base64DecodingOptions.ignoreUnknownCharacters)
    let image = UIImage(data: imageData!)
    return image!
}

这是细胞类.

class MsgWithImg: UITableViewCell {
//MARK: - Observer.
internal var valuesToDisplay: NewProjectGrpMsgModel! {
    didSet {
        imgView.image = convertBase64StringToImage(imageBase64String: valuesToDisplay.msgAttachment)
    }
}
//MARK: - Properties.
fileprivate let imgView: UIImageView = {
    let imgView = UIImageView(frame: .zero)
    imgView.clipsToBounds = true
    imgView.translatesAutoresizingMaskIntoConstraints = false
    imgView.contentMode = .scaleAspectFill
    imgView.layer.cornerRadius = 0
    return imgView
}()
//MARK: - Init.
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    backgroundColor = .clear
    clipsToBounds = true
    selectionStyle = .none
    setupViews()
}
required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}
fileprivate func setupViews() {
    contentView.addSubview(imgView)
    let imgViewConstraints = [
        imgView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 3),
        imgView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -3),
        imgView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
        imgView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -45)
    ]
    NSLayoutConstraint.activate(imgViewConstraints)
}

}我花了一些时间认为这是一个自动布局问题;或者表格行高是自动的.这就是为什么我只用图像视图构建这个测试单元类的原因.但我认为这个问题具有不同的性质.我确实阅读了很多关于我可以在这个网站上找到相关内容的答案,但我无法确定问题是什么,并且控制台没有打印出任何内容.

} I spent some time thinking that this is an auto layout problem; or the fact that the table row height is automatic. that's why I built this test cell class with only the image view. but I think this problem is of a different nature. I did read quite a few answers to what I could find relevant on this website but I cannot determine what the problem is and the console does not print out anything.

推荐答案

问题是如果你不给一个UIImageView同时指定一个宽度和一个高度,它的intrinsicContentSize 成为分配给它的图像的大小.

The problem is that if you don't give a UIImageView both a width and a height, its intrinsicContentSize becomes the size of the image assigned to it.

按原样使用您的代码,您通过约束其前导和尾随锚点为图像视图赋予了一个宽度,但没有赋予它一个高度-- 单独或单元格的高度(因为您想要自动调整单元格大小).

With your code as-is, you've given the image view a width by constraining its Leading and Trailing anchors, but you haven't given it a height -- either by itself or by the cell's height (since you want auto-sizing cells).

所以,如果我们使用这四张图片:

So, if we use these four images:

生成的表格视图如下所示:

The resulting table view looks like this:

这是 iPhone 13 上发生的事情(注意:所有尺寸都是四舍五入的)...

And here's what's happening on an iPhone 13 (note: all sizes are rounded)...

对于 100x200 图像:

For the 100x200 image:

  • 您的前导/尾随约束使图像视图框架宽 345 磅
  • 没有设置高度,因此自动布局使用图像大小(200 磅),将图像视图框架设置为 200 磅高
  • 图像视图设置为.scaleAspectFill,因此缩放后的大小为345 x 690
  • your Leading/Trailing constraints make the image view frame 345-pts wide
  • no height set, so auto-layout uses the image size (200-pts), setting the image view frame 200-pts tall
  • image view is set to .scaleAspectFill, so the scaled size is 345 x 690

对于 100x300 图像:

For the 100x300 image:

  • 您的前导/尾随约束使图像视图框架宽 345 磅
  • 未设置高度,因此自动布局使用图像大小(300 磅),将图像视图框架设置为 300 磅高
  • 图像视图设置为.scaleAspectFill,因此缩放后的大小为345 x 1035
  • your Leading/Trailing constraints make the image view frame 345-pts wide
  • no height set, so auto-layout uses the image size (300-pts), setting the image view frame 300-pts tall
  • image view is set to .scaleAspectFill, so the scaled size is 345 x 1035

对于 600x200 图像:

For the 600x200 image:

  • 您的前导/尾随约束使图像视图框架宽 345 磅
  • 没有设置高度,因此自动布局使用图像大小(200 磅),将图像视图框架设置为 200 磅高
  • 图像视图设置为.scaleAspectFill,因此缩放后的大小为600 x 200
  • your Leading/Trailing constraints make the image view frame 345-pts wide
  • no height set, so auto-layout uses the image size (200-pts), setting the image view frame 200-pts tall
  • image view is set to .scaleAspectFill, so the scaled size is 600 x 200

对于 800x600 图像:

For the 800x600 image:

  • 您的前导/尾随约束使图像视图框架宽 345 磅
  • 未设置高度,因此自动布局使用图像大小(600 磅),将图像视图框架设置为 600 磅高
  • 图像视图设置为.scaleAspectFill,因此缩放后的大小为800 x 600
  • your Leading/Trailing constraints make the image view frame 345-pts wide
  • no height set, so auto-layout uses the image size (600-pts), setting the image view frame 600-pts tall
  • image view is set to .scaleAspectFill, so the scaled size is 800 x 600

如果我们将图像视图设置为 .scaleAspectFit 可能会更清晰(红色背景以便我们可以看到框架):

It may be clearer if we set the image view to .scaleAspectFit (with a red background so we can see the frame):

作为一般规则,通常给图像视图一个固定大小(或比例大小),并使用 .scaleAspectFit 来显示完整的图像.或者,也常见的是使用预处理器来生成缩略图".表格视图单元格的大小图像.

As a general rule, it is common to give the image view a fixed size (or proportional size), and use .scaleAspectFit to show the complete images. Or, also common, to use a pre-processor to generate "thumbnail" sized images for the table view cells.

这篇关于带有 UIImage 的 Swift 5 表格视图单元格显得非常高并且图像非常缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:带有 UIImage 的 Swift 5 表格视图单元格显得非常高并且图像非常缩放

基础教程推荐