iOS UILabel没有重绘为新的大小

时间:2011-08-21 01:43:10

标签: iphone objective-c ios uitableview uilabel

我有一组显示在TableView单元格中的UILabel。当用户触摸单元格时,标签会展开以显示我放在那里的所有文本,而不是两行截断版本。

动画和扩展工作,但当我再次按下标签使其缩小TableViewCell时,标签正确调整大小,但标签没有。我已经NSLog了标签的大小,并以编程方式我的代码工作,但它无法正确绘制。

这是我的cellForRowAtIndexPath方法:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *sectionContents = [[self tableData] objectAtIndex:[indexPath section]];
    NSString *contentForRow = [sectionContents objectAtIndex:[indexPath row]];

    UILabel *label = nil;
    int noOfLines;

    UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
    label = [[UILabel alloc] initWithFrame:CGRectZero];

    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

    label.text = contentForRow;
    if ([expandedIndexPathsArray containsObject:indexPath])
        {
        noOfLines = 0;
        CGSize size = [contentForRow sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
        label.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f));
        NSLog(@"height is now %f",label.frame.size.height);
    } else {
        noOfLines = 2;
        CGSize size = [contentForRow sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
        label.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MIN(size.height, 44.0f));
         NSLog(@"height is now %f",label.frame.size.height);
    }
    NSLog(@"Number of Lines: %d",noOfLines);
    label.lineBreakMode = UILineBreakModeWordWrap;
    label.backgroundColor = [UIColor blueColor];
    label.font = [UIFont systemFontOfSize:FONT_SIZE];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    label.numberOfLines = noOfLines;
    [[cell contentView] addSubview:label];
    [label release];
    return cell;
}

有人可以告诉我这里发生了什么,因为我很难理解它。

提前致谢! :d

1 个答案:

答案 0 :(得分:1)

您发布的代码未显示(根据您的评论)将新标签叠加在旧标签上。然而,每次调用该方法时,它确实会形成一个全新的细胞。这不是通常的设计模式。

通常的模式是回收细胞,只有在没有回收细胞时才创建新细胞。使用这种方法,您需要(根据您的评论)某种方式跟踪标签。 (执行此操作的一种方法显示在下面的代码段中。)

您尚未发布tableView:heightForRowAtIndexPath:方法。根据那里发生的情况,您可能会遇到奇怪的行为,即行高与标签高度不匹配。当你在tableView上调用 reloadData (或一个相关的方法)时,也不清楚。这需要调用,因此iOS可以刷新单元格行高。也许这在你的代码中都可以 - 但绝对值得一试。

我已经测试了以下代码,它以我认为你想要在你的问题中实现的方式扩展和减少单元格。为方便起见,此代码只是测试以查看行是否与给定数字匹配以确定它是否已展开。你将[expandedIndexPathsArray containsObject:indexPath]替换为我的([indexPath row] == _pgSpecialRow)。

我已经通过添加两个额外的方法来分离工作(虽然这里的代码总数较少)。这部分是为了提高可读性,部分原因是tableView:heightForRowAtIndexPath:方法需要执行与tableView相同的总和:cellForRowAtIndexPath:method

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

    // see if there's a cell available to recylce
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (!cell)
    {
        // there's no cell to recycle, so make a new one
        // add a label to it and tag the label so we can find it later

        cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier];
        UILabel* label = [[UILabel alloc] init];

        // do set up on label that doesn't vary with cell content
        [label setTag: 101];
        label.lineBreakMode = UILineBreakModeWordWrap;
        label.backgroundColor = [UIColor blueColor];
        label.font = [UIFont systemFontOfSize:FONT_SIZE];

        [[cell contentView] addSubview:label];
        [label release];
    }

    // either on a recycled cell or on the cell just created, set the contents

    NSArray *sectionContents = [[self tableData] objectAtIndex:[indexPath section]];
    NSString *contentForRow = [sectionContents objectAtIndex:[indexPath row]];
    UILabel* label = (UILabel*)[[cell contentView] viewWithTag:101];

    [self adjustLabel: label forText:contentForRow andExpanded:([indexPath row] == _pgSpecialRow)];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}

- (void) adjustLabel: (UILabel*) label forText: (NSString*) text andExpanded: (BOOL) expanded;
{    
    label.text = text;

    CGFloat height = [self heightForLabelWithText: text expanded: expanded];
    label.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), height);

    label.numberOfLines = expanded ? 0: 2;
}


- (CGFloat) heightForLabelWithText: (NSString*) text expanded: (BOOL) expanded;
{
    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

    if (expanded)
    {
        return MAX([text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap].height, 44.0);
    }

    return MIN([text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap].height, 44.0);
}


- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *sectionContents = [[self tableData] objectAtIndex:[indexPath section]];
    NSString *contentForRow = [sectionContents objectAtIndex:[indexPath row]];

    // return a cell height that's big enough (with a bit of extra margin)
    return [self heightForLabelWithText: contentForRow expanded:([indexPath row] == _pgSpecialRow)]+ 16.0;
}