UITableView具有动态高度行的“丑陋”背景图像

时间:2010-01-18 09:36:32

标签: uitableview dynamic uiimageview height row

我创建了一个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;
}

您可能会注意到,我使用一个单独的类作为名为SessionData的UITableViewDatasource。在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;
}

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

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

2 个答案:

答案 0 :(得分:1)

这里有几点需要注意。

首先,您的单元格中会进行大量处理,这会导致设备上的滚动性能非常差。您应该更好地利用重新排列单元格并执行所有单元格中常见的大多数单元格设置:

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

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

其次,您可能希望查看stretchable images

第三,通过手动绘制单元格,您会注意到更好的性能。创建自定义视图(您添加到内容视图中),覆盖drawRect:,使用UIImage的{​​{1}}方法在其上绘制图像。这将大大加快速度!尽可能地绘制所有内容,因为子视图布局很昂贵!另外,如果可能,请确保不使用UIView(包括UIImageView,UILabel等)透明度,设置drawInRect:并设置背景颜色。最好使用opaque = YES的{​​{1}}方法在drawRect:中绘制文字,这样可以看出透明的UILabel。

但是,如果你有很少的细胞,比如< 4或者什么,那么也许绘图方法太多了。但是,仍然非常建议!

希望这有帮助!

答案 1 :(得分:0)

感谢Michael的建议。我确实可以使用以下代码修复我的图形问题:

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

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

即使我似乎没有太多的速度问题,我也按照你的建议部分地重写了我的代码,主要是通过构造代码的单元初始化部分中的单元格的主要部分。我确实注意到了一个小的速度改进,也许它在设备上更明显(与模拟器相比)。

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

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