带图像的动态 UITableView

Posted

技术标签:

【中文标题】带图像的动态 UITableView【英文标题】:Dynamic UITableView with images 【发布时间】:2017-02-10 15:34:50 【问题描述】:

有类似的问题,但没有一个答案对我有用。在动态表中,我想显示具有不同高度的图像。每个单元格都有一个UIImageViewcontentMode = .scaleAspectFit,因此图像很好地占用了表格的宽度并根据需要占用了高度。

Cell 有 4 个约束:

表格视图控制器:

class TableTableViewController: UITableViewController 

    override func viewDidLoad() 
        super.viewDidLoad()

        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableViewAutomaticDimension
    

    override func numberOfSections(in tableView: UITableView) -> Int 

        return 1
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        return 2
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ImageTableViewCell.self), for: indexPath) as! ImageTableViewCell

        let image = indexPath.row == 0 ? UIImage(named: "1.jpg")! : UIImage(named: "2.jpg")!
        cell.customImageView.image = image

        return cell
    

结果:

您可以看到单元格的高度不正确(图像视图顶部和底部的图像视图的红色背景)。我相信这是因为图像视图的intrinsicContentSize 等于图像大小,这就是单元格高度计算不正确的原因(不考虑内容模式)。我尝试计算图像的高度并为图像视图添加高度约束:

cell.heightConstraint.constant = cell.frame.width * image.size.height /  image.size.width

但它打破了单元格的内容视图约束。

项目可以下载here>>

【问题讨论】:

所以基本上你想要具有动态高度单元格的表格视图? 正确设置约束 @Dharmesh Kheni 是的,所以单元格的高度等于图像高度。 @Harish 非常有建设性的回答大声笑 【参考方案1】:

在你的ImageTableViewCell.swift

import UIKit

class ImageTableViewCell: UITableViewCell 

    @IBOutlet weak var customImageView: UIImageView!

    internal var aspectConstraint : NSLayoutConstraint? 
        didSet 
            if oldValue != nil 
                customImageView.removeConstraint(oldValue!)
            
            if aspectConstraint != nil 
                customImageView.addConstraint(aspectConstraint!)
            
        
    

    override func prepareForReuse() 
        super.prepareForReuse()
        aspectConstraint = nil
    

    func setPostedImage(image : UIImage) 

        let aspect = image.size.width / image.size.height

        aspectConstraint = NSLayoutConstraint(item: customImageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: customImageView, attribute: NSLayoutAttribute.height, multiplier: aspect, constant: 0.0)

        customImageView.image = image
    

在您的TableTableViewController.swift 中,您的cellForRowAt 方法将是:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "ImageTableViewCell", for: indexPath) as! ImageTableViewCell

    let image = imageArr[indexPath.row]
    cell.setPostedImage(image: image!)
    return cell

并以这种方式声明您的imageArr

let imageArr = [UIImage(named: "1.jpg"), UIImage(named: "2.jpg")]

您的竞争代码将是:

import UIKit

class TableTableViewController: UITableViewController 

    let imageArr = [UIImage(named: "1.jpg"), UIImage(named: "2.jpg")]
    override func viewDidLoad() 
        super.viewDidLoad()

        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableViewAutomaticDimension
    

    override func numberOfSections(in tableView: UITableView) -> Int 

        return 1
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        return 2
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "ImageTableViewCell", for: indexPath) as! ImageTableViewCell

        let image = imageArr[indexPath.row]
        cell.setPostedImage(image: image!)
        return cell
    

THIS 将是您的结果。

编辑:

修复约束问题集aspectConstraint 优先于999aspectConstraint 将是:

internal var aspectConstraint : NSLayoutConstraint? 
    didSet 
        if oldValue != nil 
            customImageView.removeConstraint(oldValue!)
        
        if aspectConstraint != nil 
            aspectConstraint?.priority = 999  //add this
            customImageView.addConstraint(aspectConstraint!)
        
    

【讨论】:

感谢您的帮助。不幸的是,您的代码打破了约束。运行时检查控制台 - 无法同时满足约束。 要修复破坏性约束,您需要将约束优先级设置为 999。当您更新它时,我会接受答案。谢谢 删除预期的大小 + automaticDimension 不会破坏我这边的任何东西(我也没有在单元格中设置任何高度)。无论如何添加它重要吗?

以上是关于带图像的动态 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

Vue绑定样式动态backgroundImage带参数使用asset

根据 UILabel 动态调整 uitableViewCell 大小(带段落间距)

火灾检测基于matlab GUI火灾检测(带面板)含Matlab源码 1646期

红外DDE算法聊聊红外图像增强算法的历史进程(第一回)

使用css将图像显示为带圆圈的图像

当我尝试上传带口罩的图像时,认知面部检测不起作用