Ios 如何在具有0到2个图像的UITableViewCell上设置可调整高度的约束?

Ios 如何在具有0到2个图像的UITableViewCell上设置可调整高度的约束?,ios,swift,uitableview,resize,nslayoutconstraint,Ios,Swift,Uitableview,Resize,Nslayoutconstraint,在对该问题的解释之后是代码 我有一个UIViewController包含一个UITableView,其中的UITableViewCell显示一个、两个或零个图像。对于一个和两个图像,单元格的高度始终为72,但如果没有任何图像,则单元格的高度必须为零。我的表格单元格中有两个UIView,第一个包含一个UIImageView,第二个包含两个。我要么隐藏要么显示相关的一个,这取决于该单元格是否有一个或两个图像。如果单元格中没有图像,则两个UIView都是隐藏的,但当然它们仍然是设置的约束的一部分,因此

在对该问题的解释之后是代码

我有一个
UIViewController
包含一个
UITableView
,其中的
UITableViewCell
显示一个、两个或零个图像。对于一个和两个图像,单元格的高度始终为72,但如果没有任何图像,则单元格的高度必须为零。我的表格单元格中有两个
UIView
,第一个包含一个
UIImageView
,第二个包含两个。我要么隐藏要么显示相关的一个,这取决于该单元格是否有一个或两个图像。如果单元格中没有图像,则两个
UIView
都是隐藏的,但当然它们仍然是设置的约束的一部分,因此生成的单元格仍然有72像素高,而我需要它折叠

有人告诉我,创建高度可调整大小的
UITableViewCell
的唯一方法是在情节提要中设置约束,并且动态地以编程方式处理约束值会导致布局问题。我不知道这些建议是否属实,因此我尝试了以下方法(没有成功):

  • 设置对my
    UIView
    NSLayoutConstraint
    的显式引用,以控制my
    ResizebleMageCell
    调用中的高度,这会导致
    无法同时满足约束
    错误;及

  • 在my
    ResizeableImageCell
    调用中,为所有控制高度的
    NSLayoutConstraint
    设置显式引用;和/或

  • 添加和删除
    UIView
    ,这两种方法都可以正常工作,直到您开始在表格中滚动,当您将手指从屏幕上抬起后,表格开始上下跳动

  • 这是控制视图控制器的当前代码:

    import UIKit
    
    class ViewController: UIViewController
    {
        @IBOutlet weak var tableView: UITableView!
    
        let imageNames = [ "room", "street", "tree" ]
    
    
    
        override func viewDidLoad ()
        {
            super.viewDidLoad()
    
            tableView.delegate = self
            tableView.dataSource = self
            tableView.rowHeight = UITableViewAutomaticDimension
            tableView.estimatedRowHeight = 44.0
        }
    
    
    
        func getRandomInt ( from start: Int, to end: Int ) -> Int
        {
            return Int( arc4random_uniform( UInt32( ( end + 1 ) - start ) ) ) + start
        }
    }
    
    
    
    extension ViewController: UITableViewDataSource
    {
        @available( iOS 2.0, * )
        public func tableView ( _ tableView: UITableView, cellForRowAt indexPath: IndexPath ) -> UITableViewCell
        {
            let cell = tableView.dequeueReusableCell( withIdentifier: "ResizableImageCell" ) as! ResizableImageCell
            let numImages = getRandomInt( from: 0, to: 2 )
    
            cell.view1.isHidden = numImages != 1
            cell.view2.isHidden = numImages != 2
    
            var rand = getRandomInt( from: 0, to: imageNames.count - 1 )
    
            switch numImages
            {
            case 1:     cell.image1.image = UIImage( named: imageNames[ rand ] )
            case 2:     cell.image2.image = UIImage( named: imageNames[ rand ] )
            default:    ()
            }
    
            guard numImages == 2 else { return cell }
    
            rand = getRandomInt( from: 0, to: imageNames.count - 1 )
    
            cell.image3.image = UIImage( named: imageNames[ rand ] )
    
            return cell
        }
    
    
    
        func tableView ( _ tableView: UITableView, numberOfRowsInSection section: Int ) -> Int
        {
            return 64
        }
    }
    
    这是控制我的定制
    resizebleimagecell
    单元格的当前代码

    import UIKit
    
    class ResizableImageCell: UITableViewCell
    {
        @IBOutlet weak var view1: UIView!
        @IBOutlet weak var view2: UIView!
    
        @IBOutlet weak var image1: UIImageView!
        @IBOutlet weak var image2: UIImageView!
        @IBOutlet weak var image3: UIImageView!
    
    
    
        override func awakeFromNib ()
        {
            super.awakeFromNib()
        }
    }
    
    下面是现有故事板的屏幕截图:


    感谢阅读。

    我在项目中使用了
    heighForRow
    函数解决了这个问题

    在ViewController中:

     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    
        //Check if you have to display images or not
    
        //return 75 or CGFloat.ulpOfOne 
    }
    
    也许使用此解决方案,您必须在
    cellforrowatinexpath
    函数之前设置
    let numImages=getRandomInt(从:0到:2)
    ,并将64个结果存储在一个数组中

    编辑: 重要提示来自:


    不要为高度返回0,否则由于rect退化,控制台中可能会出现一些自动布局错误。返回CGFloat.ulpOfOne,它是无穷小的,但仍然不是零


    在使用@Chief Lutz的
    heightForRowAt
    建议(如上所述)解决了这个问题后,我随后意识到还有另一个同样有效的解决方案。与在
    heightForRowAt
    中运行高度计算不同,可以有多个笔尖,每个笔尖设计用于处理不同数量的图像。这样做的好处是高度计算在引擎盖下进行,使代码更简单、更短;但缺点是有多个NIB,其中可能有一些重复的布局和/或约束


    如果您的单元格包含一个或多个零线
    UILabel
    ,则这种方法特别有用,因为在这种情况下,
    heightForRowAt
    所需的部分计算涉及[重新]创建单元格
    UILabel
    ,并用文本填充它们,这样他们就可以调整大小并告诉你渲染时每个单元格的高度(
    heightForRowAt
    cellForRowAt
    之前被调用)。

    谢谢@Chief Lutz,我会尝试一下,让你知道结果。因此@Chief Lutz:还没有定论,但看起来你的建议会起作用,“谢谢你!”约瑟夫·贝伊斯的母亲——希望能有所帮助。不客气:)高度不要返回0,否则控制台中可能会出现一些自动布局错误,因为您的rect已退化。返回CGFloat.ulpOfOne,它是无穷小的,但仍然不是零。