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

时间:2017-01-06 12:12:27

标签: ios swift uitableview resize nslayoutconstraint

在解释问题之后,

代码如下。

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

有人告诉我,创建可调整高度的UIView的方法是通过在故事板中设置约束,并将约束的值弄乱以编程方式即时运行将导致布局问题。我不知道这些建议是否属实,所以我尝试了以下(没有成功):

  1. 设置明确引用我的NSLayoutConstraint ResizableImageCell来控制Unable to simultaneously satisfy constraints来电中的身高,导致NSLayoutConstraint错误;和

  2. 设置对所有 ResizableImageCell的明确引用,以控制UIView来电中的身高;和/或

  3. 添加和删除ViewController,两者都可以正常工作,直到您开始滚动表格,然后在您从屏幕上抬起手指后,桌子开始上下跳跃。

  4. 这是控制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 } }

    的当前代码
    ResizableImageCell

    这是控制我的定制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() } } 单元格

    的当前代码
    foreachRDD

    以下是现有故事板的屏幕截图:

    screenshot of a storyboard from XCode

    感谢您的阅读。

2 个答案:

答案 0 :(得分:1)

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

在ViewController中:

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    //Check if you have to display images or not

    //return 75 or CGFloat.ulpOfOne 
}

也许使用此解决方案,您必须在let numImages = getRandomInt( from: 0, to: 2 )函数之前创建cellForRowAtIndexPath并将64个结果存储在数组中。

修改 来自Josh Homann的重要提示:

  

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

答案 1 :(得分:0)

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

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