2011-08-21 89 views
2

我有一组显示在TableView单元格中的UILabel。当用户触摸单元格时,标签将展开以显示我放入其中的所有文本,而不是两行截断版本。iOS 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

+0

好吧,我发现我的cellForRowAtIndexPath实际上是分层的新标签而不是先删除它们。我是否需要以某种方式编辑已存在的标签,还是删除其子视图并添加新的标签?这会发生在cellForRowAtIndexPath或didSelectRowAtIndexPath? – Chris

回答

1

您已发布的代码未出现(根据您的评论)以将新标签覆盖在旧标签上。但是,每次调用该方法时都会创建一个全新的单元格。这不是通常的设计模式。

通常的模式是回收单元格,只有在回收单元不可用时才创建新单元格。使用这种方法,您需要(根据您的评论)以某种方式跟踪标签。 (这样做的一种方式显示在下面的代码片段中。)

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

我测试了下面的代码,它扩展和减少了我认为你试图在你的问题中实现的方式的单元格。为了方便起见,这段代码只是测试一下行是否匹配给定的数字,以确定它是否被扩展。你会替换我的[[indexPath row] == _pgSpecialRow [expandedIndexPathsArray containsObject:indexPath])。

我已经通过添加两个附加方法分离了工作(尽管这里完全没有代码)。这部分是提高可读性,部分是因为的tableView:heightForRowAtIndexPath:方法需要做同样的金额为的tableView:的cellForRowAtIndexPath:方法

- (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; 
} 
+0

谢谢马修,你的代码完美地适用于我。我不得不拨弄我的didSelectRowAtIndexPath方法,但它现在完美。我不得不承认,花了我几个小时才开始工作,并了解你的代码和原因是什么,但现在我明白了。感谢您抽出时间回复!非常感激! :d – Chris