heightForRowAtIndexPath

heightForRowAtIndexPath

我正在使用Xcode4编写一个简单的iOS应用,该应用使用表格 View 来显示故事列表(从URL获取)。我将故事标题显示为UILabel,并显示为表格单元格的 subview 。

我重写heightForRowAtIndexPath以根据每个故事标题的长度为单元格计算正确的高度。我将标签添加到cellForRowAtIndexPath的单元格中。当我在模拟器中运行该应用程序时,一切都呈现良好。但是:当我向下滚动并向上滚动时,标签会弄乱。它们被截断并超限运行。我进行了一点调试,发现滚动期间未触发heightForRowAtIndexPath方法,因此未重新计算像元高度,因此标签文本溢出并变得难看。以下是相关代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        [cell autorelease];
    }

    /* NOTE: code to load trimmedTitle dynamically is snipped */
    NSString* trimmedTitle;

    UIFont *cellFont = [UIFont fontWithName:@"Georgia" size:14.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [trimmedTitle sizeWithFont:cellFont constrainedToSize:constraintSize
                                    lineBreakMode:UILineBreakModeWordWrap];

    UILabel* tempLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, 230, labelSize.height)];
    tempLabel.lineBreakMode = UILineBreakModeWordWrap;
    tempLabel.text = trimmedTitle;
    tempLabel.numberOfLines = 0;

    [cell.contentView addSubview:tempLabel];
    [tempLabel release];

    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString* cellText;  // code to load cellText dynamically is snipped off
    UIFont *cellFont = [UIFont fontWithName:@"Georgia" size:14.0];
    CGSize constraintSize = CGSizeMake(230.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

最佳答案

在这种情况下,我通常会预先计算所有行的高度,将它们存储在数组中,然后以heightForRowAtIndexPath返回这些高度。这样,tableview知道每个单元格的高度,并且即使在重用之后,单元格也应符合该高度。我不知道有什么方法可以强制计算像元高度,而不仅仅是寻找何时可以看到并重新加载像元,这似乎太昂贵了。

更新:一些示例代码:

我有一个称为- (void)calculateHeights的方法,该方法执行与heightForRowAtIndexPath中相同的计算,但是将结果存储在我的可变数组heights_ ivar中:

- (void)calculateHeights {
    [heights_ removeAllObjects]
    for (Widget *myWidget in modelWidgetArray) {
        NSString* cellText;  // code to load cellText dynamically is snipped off
        UIFont *cellFont = [UIFont fontWithName:@"Georgia" size:14.0];
        CGSize constraintSize = CGSizeMake(230.0f, MAXFLOAT);
        CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

        [heights_ addObject:[NSNumber numberWithFloat:labelSize.height + 20.0f]];
    }
}

然后在heightForRowAtIndexPath中,给出一个1-section表 View :
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [heights_ objectAtIndex:[indexPath row]];
}

如果表 View 有多个部分,则需要做一些数学运算以转换​​为一维heights_数组,然后再次返回。另外,任何时候您使用-reloadData时,也都需要使用-calculateHeights

关于objective-c - iOS-在滚动过程中不会触发heightForRowAtIndexPath,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7577770/

10-10 21:05