UITableViewCell框架高度不匹配tableView:heightForRowAtIndexPath: [英] UITableViewCell frame height not matching tableView:heightForRowAtIndexPath:

查看:222
本文介绍了UITableViewCell框架高度不匹配tableView:heightForRowAtIndexPath:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个具有可变高度自定义表格单元格的UITableView,它们的高度由包含的多行UILabel的大小决定。我已经使用 sizeWithFont:constrainedToSize:

I'm constructing a UITableView with variable height custom table cells, their height determined by the size of a contained multi-line UILabel. I've got the tableView:heightForRowAtIndexPath: delegate method wired up and calculating the final height correctly using sizeWithFont:constrainedToSize:.

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

I've run across strange issue: by the time the data source method tableView:cellForRowAtIndexPath: is called, the correct per-row height has already been determined as described above, but the frame of the cell does not match that height. Instead, the frame.size.height property of the cell is the default cell height of the table view (86 px, as I've set it in Interface Builder, the correct height when the contained UILabel has just one line of text), instead of being the height that tableView:heightForRowAtIndexPath: determined correct for that index path.

我在 cellForRowAtIndexPath:中使用出列产生单元格,即

I'm producing the cells in cellForRowAtIndexPath: using dequeuing, that is,

// 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属性来匹配计算出的高度。这本身就不那么令人惊讶,因为细胞实例而不是它们的几何体而引起了人们的关注。但是,单元格正确呈现,因此高度属性设置为某处,但它发生在 cellForRowAtIndexPath:之后。

It seems, then, that whatever iOS is doing behind the scenes, the dequeuing is not setting the frame property of the cell to match the calculated height. This in itself is not that surprising, dequeuing concerns itself with cell instances, not their geometry. The cells are rendered correctly, though, so the height property is being set somewhere, but it happens after cellForRowAtIndexPath:.

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

So: when I initially populate the table view, cell.frame.size.height is 86 for all the cells as they appear for the first time when I scroll the list downwards. Since the correct geometry is set sometime after the first cellForRowAtIndexPath: for each row before it's displayed, when I scroll back up, the height property is correct for each cell that comes back into view after being reused.

此后我可以随意来回滚动表视图,并且从该点开始,每个单元格的height属性保持正确。

After this I can scroll the table view back and forth at will, and the height property remains correct for each cell from that point on.

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

What's the correct way of getting the correct cell height the first time around, before any dequeue-based reuse happens? I need this to do a bit of re-positioning of the subviews of the table cell. Do I need to manually call heightForRowAtIndexPath: in cellForRowAtIndexPath: and then manually set the frame of the freshly created CustomCell instance to match that height? This seems redundant, and I'd need to create a mechanism to detect when the cell is created for the first time with the wrong frame height vs. when it is dequeued with the correct frame height later to avoid this redundancy.

所以,如果有人能够了解这背后的逻辑,我会很感激。

So, if someone can shed some light into what the logic is behind this, I'd appreciate it.

推荐答案

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

As suggested by Flexo, answering this myself is apparently better than adding an edit to the question. So, here's the previous edit as an answer:

没关系,我应该更好地阅读文档。我可以在 tableView中找到正确的框架:willDisplayCell:forRowAtIndexPath: UITableViewDelegate 的方法,所以这是正确的地方做依赖于正确设置框架的子视图自定义,而不是 cellForRowAtIndexPath:

Nevermind, I should read the docs better. I can get the correct frame in the tableView:willDisplayCell:forRowAtIndexPath: method of UITableViewDelegate, so that is the correct place to do subview customization that relies on the correct frame being set, not cellForRowAtIndexPath:.

有趣的是文档说但是:


委托返回后,表格视图仅设置 alpha frame 属性,然后仅在行滑入或滑出时为其设置动画。

After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out.

...因为调用此委托方法时正确的帧已存在。但无论如何,问题已经解决了。

...since the correct frame is already there when this delegate method is called. But anyway, problem solved.

这篇关于UITableViewCell框架高度不匹配tableView:heightForRowAtIndexPath:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆