0

我创建了一个 UITableViewController,它根据包含的文本量计算每行的高度。计算行高的代码如下所示:

- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    Message *message = [[[[SessionData sharedSessionData] sessions] objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
    CGSize size = [[message text] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    return size.height + (CELL_CONTENT_MARGIN * 2) + 38;
}

正如您可能注意到的,我使用了一个单独的类作为 UITableViewDatasource,称为 SessionData。在 SessionData 类中,我绘制行。每行都有一个顶部图像、中心图像(根据行高重复)和底部图像。我的问题如下:中心图像比底部和顶部图像更暗。我的猜测是这与图像的重复性质有关,因为顶部和底部的图像绘制得很好。以下代码是我的 [tableView:cellForRowAtIndexPath:] 消息的一部分:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // other stuff here, most likely not related to my issue ...

    Message *message  = [[sessions objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];       
    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    CGSize size = [[message text] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    [label setText:[message text]];
    [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN - 5.0f, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), size.height)];
    [label setBackgroundColor:[UIColor clearColor]];

    viewTop = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im1 top.png"]];
    viewMid = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im1 mid.png"]];
    viewBot = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im1 bot.png"]];      

    [viewTop setFrame:CGRectMake(0.0, 0.0, 300.0, 17.0)];
    [viewMid setFrame:CGRectMake(0.0, 17.0, 300.0, size.height - 10)];
    [viewBot setFrame:CGRectMake(0.0, 17.0 + size.height - 10, 300.0, 31.0)];

    [viewTop setBackgroundColor:[UIColor clearColor]];
    [viewMid setBackgroundColor:[UIColor clearColor]];
    [viewBot setBackgroundColor:[UIColor clearColor]];  

    [cell.backgroundView setBackgroundColor:[UIColor clearColor]];

    [((UIImageView *)cell.backgroundView) addSubview:viewTop];  
    [((UIImageView *)cell.backgroundView) addSubview:viewMid];  
    [((UIImageView *)cell.backgroundView) addSubview:viewBot];

    [[cell backgroundView] addSubview:label];   

    return cell;
}

我的猜测是我需要为顶部、中心和底部图像视图创建一个具有总大小(宽度、高度)的 containerView,并将 containerView 添加到单元格中,但这似乎不起作用。任何人都知道如何解决这个问题?

请注意:我的 UITableViewController 有一个渐变作为背景图像。所以顶部/中心/底部图像绘制在背景渐变的顶部。也许这也是问题的一部分。

4

2 回答 2

1

这里有几点需要注意。

首先,您的单元格中正在进行大量处理,这将导致设备上的滚动性能非常差。您应该更好地利用重新排队单元并执行此处所有单元共有的大部分单元设置:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        // Do cell layout in here!
    }

这样,单元格及其子视图可以重复使用,而不是每次单元格出现在屏幕上时都重新创建(使用视图的tag属性和viewWithTag:方法)。

其次,您可能希望查看可拉伸图像

第三,您会注意到手动绘制单元格的性能要好得多。创建一个自定义视图(您将其添加到内容视图中),覆盖,使用's方法drawRect:在其上绘制图像。这将大大加快速度!尽可能绘制所有内容,因为子视图布局很昂贵!此外,如果可能,请确保不使用 UIView(包括 UIImageView、UILabel 等)透明度,设置和设置背景颜色。最好使用'方法在 中绘制文本,这将提供透明 UILabel 的外观。UIImagedrawInRect:opaque = YESdrawRect:NSStringdrawInRect:

但是,如果您的单元格非常少,例如 < 4 之类的,那么绘图方法可能太多了。但是,仍然非常建议!

希望这可以帮助!

于 2010-01-18T09:50:22.033 回答
0

感谢您的建议迈克尔。我确实可以使用以下代码解决我的图形问题:

[bubbleView setImage:[bubble stretchableImageWithLeftCapWidth:165 topCapHeight:30]];

我现在可以使用 1 个图像,而不是使用 3 个单独的图像来创建聊天气泡,并且它可以优雅地伸展。确实是一个非常好的建议:)

尽管我似乎没有太多速度问题,但我确实按照您的建议部分重写了我的代码,主要是通过在代码的单元初始化程序部分中构造单元的主要部分。我确实注意到速度略有提高,也许它在设备上更明显(与模拟器相比)。

目前,我仍然使用 ImageView 绘制图像(您可能会注意到),每当我需要更快的渲染速度时,我都会查看 [UIImage drawInRect:]。

感谢您的建议,非常感谢。

于 2010-01-18T13:58:45.950 回答