Ios 设置UITableViewCell高度和自动布局中的多行UIButton
我有一个带有自定义Ios 设置UITableViewCell高度和自动布局中的多行UIButton,ios,objective-c,swift,uitableview,autolayout,Ios,Objective C,Swift,Uitableview,Autolayout,我有一个带有自定义UITableView单元格的UITableView,每个单元格内部都有一个ui按钮。我正在从数组中设置按钮的标题,因此按钮的大小会根据标题而变化。我需要在heightforrowatinexpath事件中根据内部按钮的大小返回正确的高度 由于我使用自动布局,我为按钮的高度约束创建了一个出口,并在单元格的layoutSubviews()事件中更新它,如下所示: class CustomCell: UITableViewCell { /* ... */ ove
UITableView单元格的UITableView
,每个单元格内部都有一个ui按钮。我正在从数组中设置按钮的标题,因此按钮的大小会根据标题而变化。我需要在heightforrowatinexpath
事件中根据内部按钮的大小返回正确的高度
由于我使用自动布局,我为按钮的高度约束创建了一个出口,并在单元格的layoutSubviews()
事件中更新它,如下所示:
class CustomCell: UITableViewCell {
/* ... */
override func layoutSubviews() {
super.layoutSubviews()
self.myButton?.layoutIfNeeded()
self.heightConstraint?.constant = self.myButton!.titleLabel!.frame.size.height
}
}
然后根据按钮高度和上下边距返回高度,如下所示:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomCell
cell.myButton?.setTitle(self.data[indexPath.row], forState: UIControlState.Normal)
cell.bounds = CGRectMake(0, 0, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds))
cell.setNeedsLayout()
cell.layoutIfNeeded()
return cell.myButton!.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height + (cell.topMarginConstraint!.constant * 2) /* top-bottom margins */ + 1 /* separator height */
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomCell
cell.myButton?.setTitle(self.data[indexPath.row], forState: UIControlState.Normal)
return cell
}
在第一次发射时,似乎没有问题。然而,在我开始滚动之后,一些行的高度似乎是错误的。当我回到顶端时,我看到先前的细胞高度也被打破了
当我在谷歌上搜索类似的问题时,问题似乎是关于可重复使用的电池,尽管我无法找到另一种计算高度的方法。怎样才能正确地重用单元,或者通过另一种方法获得正确的高度
更多信息和源代码:
IB设置的约束如下:
class CustomCell: UITableViewCell {
/* ... */
override func layoutSubviews() {
super.layoutSubviews()
self.myButton?.layoutIfNeeded()
self.heightConstraint?.constant = self.myButton!.titleLabel!.frame.size.height
}
}
这是第一次发射的电池:
滚动一段时间后:
项目的完整代码可在上找到。根据
将tableView配置为
func configureTableView() {
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160.0
}
在viewDidLoad方法中调用它
然后将uibutton高度约束配置为大于或等于
覆盖func tableView(tableView:UITableView,estimatedHeightForRowAtIndexPath:nsindepath)->CGFloat
您可以在其中放置估算高度代码
首先,最好在UIView的func updateConstraints()
方法中执行约束更新。所以不是
override func layoutSubviews() {
super.layoutSubviews()
self.myButton?.layoutIfNeeded()
self.heightConstraint?.constant = self.myButton!.titleLabel!.frame.size.height
}
我愿意
override func updateConstraints() {
self.myButton?.layoutIfNeeded()
self.heightConstraint?.constant = self.myButton!.titleLabel!.frame.size.height
super.updateConstraints()
}
请注意,应该在最后调用超级实现,而不是在开始时调用。然后调用cell.setNeedsUpdateConstraints()
来触发约束更新过程
此外,您不应该像在heightforrowatinepath:
方法中那样直接操纵单元格边界,即使您完全确定直接操纵是您想要的,也应该操纵cell.contentView
的边界,而不是单元格的边界。如果希望根据内容的尺寸动态调整单元格高度,则应使用自调整大小的单元格。如果您需要支持iOS 7,那么将告诉您如何仅使用autolayout实现该行为(不涉及边界等)
要重申答案,您应该执行以下操作:
func viewDidLoad() {
self.dummyCell = CustomCell.init()
// additional setup
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
self.dummyCell.myButton?.setTitle(self.data[indexPath.row], forState: UIControlState.Normal)
self.dummyCell.layoutIfNeeded() // or self.dummyCell.setNeedsUpdateConstraints() if and only if the button text is changing in the cell
return self.dummyCell.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
}
请知道,我链接到的答案概述了通过autolayout获得单元格高度的策略,因此仅编写我建议的代码更改是不够的,除非您以某种方式设置约束以使此解决方案有效。更多信息请参考该答案。
希望有帮助 首先,移除按钮的高度约束,并用单元格将其绑定到顶部和底部
然后,在单元格的高度中,根据按钮的宽度和字体计算文本的高度。这将使细胞的高度动态,你将不再需要高度约束
请参阅下面的链接以获取文本的高度:
希望能有帮助。如果您需要进一步帮助或了解任何内容,请告诉我:) 在CellforRowatineXpath下,我没有任何变化;在heightForRowAtIndexPath下,EXC_BAD_ACCESS.@kubilay,尝试将uibutton height constarint设置为大于或等于,并在viewDidLoad tableView中。rowHeight=UITableViewAutomaticDimensionsTryed,数量较少,但仍有断开的高度。虽然这对UILabels有效,但对uibutton无效。