【问题标题】:UITableViewCell frame height not matching tableView:heightForRowAtIndexPath:UITableViewCell 框架高度不匹配 tableView:heightForRowAtIndexPath:
【发布时间】:2012-08-07 13:47:27
【问题描述】:

我正在构建一个具有可变高度自定义表格单元格的 UITableView,它们的高度由包含的多行 UILabel 的大小决定。我已经连接了tableView:heightForRowAtIndexPath: 委托方法,并使用sizeWithFont:constrainedToSize: 正确计算了最终高度。

我遇到了一个奇怪的问题:在调用数据源方法tableView:cellForRowAtIndexPath: 时,已经如上所述确定了正确的每行高度,但单元格的框架与该高度不匹配。相反,单元格的frame.size.height 属性是表格视图的默认单元格高度(86 px,因为我在 Interface Builder 中设置了它,当包含的 UILabel 只有一行文本时的正确高度),而不是是 tableView:heightForRowAtIndexPath: 确定为该索引路径正确的高度。

我正在使用 dequeuing 生成 cellForRowAtIndexPath: 中的单元格,即

// Using storyboards, this never returns nil, no need to check for it
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"SomeIdentifier"];
NSLog(@"%f", cell.frame.size.height); // 86, not correct if the cell contains a multi-line UILabel

看来,无论 iOS 在幕后做什么,出队都没有设置单元格的 frame 属性以匹配计算的高度。这本身并不令人惊讶,出队关注的是单元实例,而不是它们的几何形状。不过,单元格已正确呈现,因此在某处设置了 height 属性,但它发生在 cellForRowAtIndexPath: 之后。

所以:当我最初填充表格视图时,cell.frame.size.height 对于所有单元格都是 86,因为当我向下滚动列表时它们第一次出现。由于正确的几何图形是在每行显示之前的第一个 cellForRowAtIndexPath: 之后的某个时间设置的,因此当我向上滚动时,height 属性对于重用后返回视图的每个单元格都是正确的。

之后我可以随意来回滚动表格视图,并且从那时起每个单元格的高度属性保持正确。

在任何基于出队的重用发生之前,第一次获得正确单元格高度的正确方法是什么?我需要这个来重新定位表格单元格的子视图。我是否需要在cellForRowAtIndexPath: 中手动调用heightForRowAtIndexPath:,然后手动设置新创建的CustomCell 实例的框架以匹配该高度?这似乎是多余的,我需要创建一种机制来检测第一次创建单元格时帧高度错误,以及稍后以正确帧高度出列时,以避免这种冗余。

所以,如果有人能阐明这背后的逻辑,我将不胜感激。

【问题讨论】:

    标签: ios objective-c uitableview reusability heightforrowatindexpath


    【解决方案1】:

    我发现最简单的方法就是在对单元进行任何设置之前致电cell.layoutIfNeeded()。这样可以确保计算所有布局约束并设置框架。

    【讨论】:

      【解决方案2】:

      不要忘记单元格是UIView,因此覆盖layoutSubviews 也是获取正确框架和调整子视图大小/位置的有效方法。只是不要忘记致电[super layoutSubviews]

      【讨论】:

        【解决方案3】:

        正如 Flexo 所建议的,自己回答这个问题显然比对问题添加编辑要好。所以,这是以前的编辑作为答案:


        没关系,我应该更好地阅读文档。我可以在UITableViewDelegatetableView:willDisplayCell:forRowAtIndexPath: 方法中获得正确的框架,因此这是进行子视图自定义的正确位置,它依赖于设置的正确框架,而不是cellForRowAtIndexPath:

        有趣的是,文档是这样说的:

        delegate 返回后,表格视图仅设置 alphaframe 属性,然后仅在行滑入或滑出时设置动画。

        ...因为调用此委托方法时已经存在正确的帧。不过不管怎样,问题解决了。

        【讨论】:

        • 最初的问题确实很好,但是这个答案不是很好。愿意分享您是如何解决问题的吗?
        猜你喜欢
        • 2015-04-29
        • 2015-12-15
        • 1970-01-01
        • 2022-09-23
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 2011-06-02
        相关资源
        最近更新 更多