【问题标题】:Settings UITableViewCell Heights With Multiline UIButtons in Auto Layout在自动布局中使用多行 UIButton 设置 UITableViewCell 高度
【发布时间】:2015-06-30 07:24:11
【问题描述】:

我有一个带有自定义UITableViewCells 的UITableView,每个内部都有一个UIButton。我正在从数组中设置按钮的标题,因此按钮的大小会根据标题而变化。我需要根据heightForRowAtIndexPath 事件中内部按钮的大小返回正确的高度。

由于我使用的是自动布局,因此我为按钮的高度约束创建了一个出口,并在单元格的 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 设置的约束如下:

这是第一次发布时的单元格:

滚动后:

项目的完整代码可以在Github找到。

【问题讨论】:

    标签: ios objective-c swift uitableview autolayout


    【解决方案1】:

    根据this

    将tableView配置为

    func configureTableView() {
      tableView.rowHeight = UITableViewAutomaticDimension
      tableView.estimatedRowHeight = 160.0
    }
    
    1. 在 viewDidLoad 方法中调用它

    2. 比将您的 uibutton 高度约束配置为大于或等于。

    3. 覆盖func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat,您可以在其中放置估计高度代码

    【讨论】:

    • 我在 cellForRowAtIndexPath 下没有任何变化;在 heightForRowAtIndexPath 下,EXC_BAD_ACCESS。
    • @kubilay,尝试将uibutton高度约束设置为大于或等于并且在viewDidLoad tableView.rowHeight = UITableViewAutomaticDimension
    • 试过了,数量少了,但还是有破高度。
    【解决方案2】:

    首先,最好在 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() 来触发约束更新传递。

    此外,您永远不应该像在heightForRowAtIndePath: 方法中那样直接操作单元格边界,即使您完全确定直接操作是您想要的,您也应该操作cell.contentView 的边界,而不是cell 的界限。如果您希望根据内容的尺寸动态调整单元格高度,则应使用自调整大小的单元格。如果您需要支持 iOS 7,那么this answer 会告诉您如何仅通过自动布局实现该行为(不触及边界等)。

    要重申答案,您应该这样做:

    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
    }
    

    请知道我链接到的答案概述了通过自动布局获取单元格高度的策略,因此仅编写我建议的代码更改是不够的,除非您以使该解决方案有效的方式设置约束。请参阅该答案以获取更多信息。 希望对您有所帮助!

    【讨论】:

      【解决方案3】:

      首先,去掉button的高度约束,用cell绑定到top和bottom。

      然后,在单元格的高度中,根据按钮的宽度和字体计算文本的高度。这将使单元格的高度动态化,您将不再需要高度限制。

      参考以下链接获取文字高度: Adjust UILabel height to text

      希望对您有所帮助。如果您需要进一步帮助或了解任何内容,请告诉我.. :)

      【讨论】:

      • 虽然这适用于 UILabel,但不适用于 UIButton。
      猜你喜欢
      • 2015-01-19
      • 2014-01-03
      • 2013-12-20
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2014-07-13
      相关资源
      最近更新 更多