ios - cellForRowAtIndexPath 在加载时将单元格视为不同的高度,然后重新加载?

标签 ios objective-c uitableview heightforrowatindexpath

前言:这是一个很抽象的问题。

我在 UITableView 中有一些单元格使用不同的图像,具体取决于单元格的高度(以 50 像素为增量,从 50 像素到 1000 像素高)。我遇到了一个奇怪的问题,当应用程序首次加载时,cellForRowAtIndexPath 报告前三个单元格(无论是否所有三个单元格都在屏幕上)的高度为 100px,然后当我向下滚动时并再次备份,他们的高度恢复到正确的值。屏幕上没有高度变化,只有使用的图像发生变化,以及我的 NSLog 语句中 cell.frame.size.height 的值。

我一直在登录 heightForRowAtIndexPathcellForRowAtIndexPath,当它们离开 heightForRowAtIndexPath 时,我可以验证高度是否正确。但是,当输入 cellForRowAtIndexPath 时,前三个高度都统一设置为 100。然后我向下滚动直到这三个单元格离开屏幕,然后向上滚动,.height 值已更改为正确的值。

总而言之,我的问题是:

heightForRowAtIndexPath 的最后和 cellForRowAtIndexPath 的开头之间是否调用了任何可能会改变 cell.frame.size 的代码.height 这些前几个单元格的值?

为什么这个问题只发生在前三个单元格上?而且,为什么他们会在片刻后重新加载时恢复原状?我认为重用标识符可能是原因,但它们在首次加载时仍被分配了该标识符,所以这无关紧要,不是吗?

编辑:我认为 100 像素的高度来自 Storyboard中原型(prototype)单元格的行高,就好像我将其更改为 101 像素一样,那么前三个单元格最初为 101 像素。

编辑:这是我用来设置图像的代码,尽管这部分可以正常工作,但它的值是错误的:

UIImage *cappedBG;
float cellHeight = cell.contentView.frame.size.height;

if (cellHeight <= 51) {
    cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 101) {
    cappedBG = [[UIImage imageNamed: @"bg100.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 151) {
    cappedBG = [[UIImage imageNamed: @"bg150.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 201) {
    cappedBG = [[UIImage imageNamed: @"bg200.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else {
    cappedBG = [[UIImage imageNamed: @"bg250.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} 

最佳答案

您不能依赖 tableView:cellForRowAtIndexPath: 中单元格的框架。您在该方法中配置的单元格的框架将在代码从此方法返回后设置。

您获得的值不是该特定行的实际高度。您从刚刚出列的单元格中获取高度。如果没有要出列的单元格,则使用刚创建的单元格的高度。 100 可能是 Storyboard/ Nib 中单元格的高度。
该高度与将要显示的单元格的高度无关。

由于您已经在 tableView:heightForRowAtIndexPath: 中计算了行高,因此请使用该值。

float cellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];

if (cellHeight <= 51) {
    cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
...

关于ios - cellForRowAtIndexPath 在加载时将单元格视为不同的高度,然后重新加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15501712/

相关文章:

ios - 有人正在使用新的iOS 11.4.1经历无限的“等待”吗?

iphone - UIViews-masked-off-area-still-touchable

uitableview - 专注于 UISearchBar 但键盘没有出现

ios - UIScrollview 在向下滚动并推送新的 View Controller 后向上移动内容

objective-c - #import Objective-C : Am I doing this wrong?

ios - 在 UITableView 中一次只允许选中一行,保留动画

ios - 点击 UITableViewCell 中的按钮时调整其大小

ios - 如何检查用户是否已登录以及是否未重定向到登录屏幕

ios - 在新 ViewController 中使用代码时发送到实例的 UIButton 无法识别的选择器

ios - 为什么我不能按 CTRL 键拖动 Storyboard的 Action ?