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
的唯一方法是在情节提要中设置约束,并且动态地以编程方式处理约束值会导致布局问题。我不知道这些建议是否属实,因此我尝试了以下方法(没有成功):
UIView
的NSLayoutConstraint
的显式引用,以控制myResizebleMageCell
调用中的高度,这会导致无法同时满足约束
错误;及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,它是无穷小的,但仍然不是零。