iOS 8 UITableView第一行的高度错误

时间:2014-12-03 19:44:56

标签: ios objective-c uitableview swift uilabel

我正在开发一个我面临一个奇怪问题的应用。我在故事板中创建了一个UITableViewController并添加了一个原型单元格。在这个单元格中,我添加了一个UILabel元素,这个UILabel占据了整个单元格。我已经使用自动布局进行了设置,并添加了左,右,顶部和底部约束。 UILabel包含一些文字。

现在在我的代码中,我初始化了表视图的rowHeight和estimatedRowHeight:

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 50
}

我按如下方式创建单元格:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell : UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("HelpCell") as? UITableViewCell
    if(cell == nil) {
        cell = UITableViewCell(style: .Default, reuseIdentifier: "HelpCell")
    }
    return cell!
}

我在表格视图中返回两行。这就是我的问题:第一行的高度是大的。似乎第二排,第三排等都具有正确的高度。我真的不明白为什么会这样。有人可以帮我这个吗?

5 个答案:

答案 0 :(得分:17)

我有一个问题,细胞'在第一次加载时高度不正确,但在向上和向下滚动细胞后#39;高度是固定的。

我尝试了所有不同的修复程序'对于这个问题,然后最终发现在最初调用self.tableView.reloadData之后调用这些函数。

            self.tableView.reloadData()
            // Bug in 8.0+ where need to call the following three methods in order to get the tableView to correctly size the tableViewCells on the initial load.
            self.tableView.setNeedsLayout()
            self.tableView.layoutIfNeeded()
            self.tableView.reloadData()

仅在初始加载后执行这些额外的布局调用。

我在这里找到了非常有用的信息:https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8/issues/10

<强>更新 有时您可能还必须在heightForRowAtIndexPath中完全配置您的单元格,然后返回计算的单元格高度。请查看此链接以获取相关示例http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout,特别是heightForRowAtIndexPath上的部分。

更新2:我还发现非常有利于覆盖estimatedHeightForRowAtIndexPath并提供一些准确的行高估算值。如果您的UITableView单元格可以是各种不同的高度,这将非常有用。

这是estimatedHeightForRowAtIndexPath的一个人为的示例实现:

public override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyCell

    switch cell.type {
    case .Small:
        return kSmallHeight
    case .Medium:
        return kMediumHeight
    case .Large:
        return kLargeHeight
    default:
        break
    }
    return UITableViewAutomaticDimension
}

更新3: UITableViewAutomaticDimension已修复iOS 9(呜呜!)。因此,您的 应自动调整大小,而无需手动计算单元格高度。

答案 1 :(得分:2)

正如Apple在setNeedsLayout

的描述中所述
  

此方法不强制立即更新,而是等待下一个更新周期,您可以在更新任何视图之前使用它来使多个视图的布局无效。此行为允许您将所有布局更新合并到一个更新周期,这通常会提高性能。

因此,您应该在dispatch_after block中添加所需的代码行(应该使用正确的布局执行)(这会将您的方法放在RunLoop的队列中)。并且您的代码将在需要布局应用后执行。

示例:

- (void)someMethod {

[self.tableView reloadData];

[self.tableView setNeedsLayout];

[self.tableView layoutIfNeeded];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            //code which should be executed with the right size of table

        });

答案 2 :(得分:0)

在iOS 8中,为estimatedRowHeight分配一个值会打开新的iOS 8自动行高计算功能。这意味着单元格的高度是通过从内到外使用其内部约束得出的。如果这些约束有问题,你会得到奇怪的结果。所以你的细胞限制有问题。它们可能含糊不清;这是不一致的通常原因。然而,我可以告诉你,因为你实际上没有显示/描述约束。

答案 3 :(得分:0)

我建议删除UILabel上的底部约束。它将根据文本调整大小,单元格也应调整大小。

如果仍无法解决问题,请尝试在viewDidLoad()中添加以下内容:

self.tableView.reloadData()

答案 4 :(得分:0)

这对我有用

- (void)layoutSubviews
{
    [super layoutSubviews];
    // Your implementation
}

我从这里得到了这个&gt;&gt; http://askstop.com/questions/2572338/uitableview-displays-separator-at-wrong-position-in-ios8-for-some-cells