我有一组显示在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
答案 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;
}