代码如下。
我的UIViewController
包含UITableView
,UITableViewCell
其中包含一张,两张或零图像。对于一个和两个图像,单元格的高度始终为72,但没有任何图像需要为零。我的表格单元格中有两个UIView
,其中第一个包含一个UIImageView
,第二个包含其中两个UIView
。我隐藏或显示相关的一个,取决于该单元格是否有一个或两个图像。如果单元格图像为零,则UITableViewCell
都被隐藏,但当然它们仍然构成约束设置的一部分,因此得到的单元格仍然是72像素高,而我需要折叠
有人告诉我,仅创建可调整高度的UIView
的方法是通过在故事板中设置约束,并将约束的值弄乱以编程方式即时运行将导致布局问题。我不知道这些建议是否属实,所以我尝试了以下(没有成功):
设置明确引用我的NSLayoutConstraint
ResizableImageCell
来控制Unable to simultaneously satisfy constraints
来电中的身高,导致NSLayoutConstraint
错误;和
设置对所有 ResizableImageCell
的明确引用,以控制UIView
来电中的身高;和/或
添加和删除ViewController
,两者都可以正常工作,直到您开始滚动表格,然后在您从屏幕上抬起手指后,桌子开始上下跳跃。
这是控制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
以下是现有故事板的屏幕截图:
感谢您的阅读。
答案 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
)。