【问题标题】:iOS 8 UITableView first row has wrong heightiOS 8 UITableView 第一行的高度错误
【发布时间】:2015-02-01 12:33:50
【问题描述】:

我正在开发一个遇到奇怪问题的应用程序。我在情节提要中创建了一个 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!
}

我在表格视图中返回两行。我的问题来了:第一行的高度太大了。看来第二行、第三行等都有正确的高度。我真的不明白为什么会这样。有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: ios objective-c uitableview swift uilabel


    【解决方案1】:

    我遇到了一个问题,第一次加载时单元格的高度不正确,但在上下滚动后,单元格的高度是固定的。

    我针对这个问题尝试了所有不同的“修复”,然后最终发现在最初调用 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 修复(哇哦!)。因此,您的单元格应该自动调整大小,而无需手动计算单元格高度。

    【讨论】:

      【解决方案2】:

      正如苹果在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
      
              });
      

      【讨论】:

        【解决方案3】:

        在 iOS 8 中,为 estimatedRowHeight 赋值会开启新的 iOS 8 自动行高计算功能。这意味着单元格的高度是通过从内到外使用其内部约束得出的。如果这些约束有问题,你会得到奇怪的结果。所以你的单元格约束有问题。它们可能是模棱两可的;这是不一致的通常原因。不过,我只能告诉你这些,因为你实际上并没有展示/描述约束。

        【讨论】:

        • 我很确定我的约束没有歧义,因为我在 UILabel 上只有 4 个约束。您还有什么其他建议可能是错误的吗?
        • 不要“非常确定”。有一些方法可以确定您是否有不明确的布局。使用它们。不要使用你的直觉;这是问题,而不是解决方案。如果您知道什么是明确的布局,我们就不会在这里遇到您的麻烦,对吗?听我说什么。一个简单的事实是,固定左、右、上和下的 4 个约束不够。您的约束可能模棱两可。
        【解决方案4】:

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

        如果这不能解决问题,请尝试在 viewDidLoad() 中添加以下内容:

        self.tableView.reloadData()

        【讨论】:

        • 感谢您的建议,但如果我删除约束,UILabel 将不会自行调整大小。此外,重新加载数据并不能解决问题。
        • 能否分享您与单元格的约束截图?
        【解决方案5】:

        这对我有用

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-05-21
          • 1970-01-01
          • 1970-01-01
          • 2017-03-09
          • 2016-11-11
          • 1970-01-01
          • 1970-01-01
          • 2014-01-20
          相关资源
          最近更新 更多