首次显示表时,不显示UITableViewCell子视图

时间:2012-07-23 01:44:20

标签: ios uitableview subview addsubview

我正在尝试向我的表格单元格添加删除线标签(以BOOL hasStrikethrough为条件)。问题是首次显示表时不会出现删除线(即使hasStrikethrough == YES)。如果滚动表格,则会重新显示行并显示正确的删除线。删除线只是一个UILabel,它被添加为UITableViewCell的子视图。

这是我的cellForRowAtIndexPath代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

static NSString *CellIdentifier = @"ItemCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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


Item  *item = [self.fetchedResultsController objectAtIndexPath:indexPath];

cell.textLabel.text = item.itemName;
cell.textLabel.textAlignment = UITextAlignmentLeft;
cell.showsReorderControl = YES;
cell.shouldIndentWhileEditing = NO;

if ([[item hasStrikethrough] boolValue] == YES) {
    [self addStrikethrough:cell];
}

return cell;
}

以下是addStrikethrough的代码:

- (void)addStrikethrough:(UITableViewCell*)cell
{
CGRect frame = cell.textLabel.frame;
UILabel *strikethrough = [[UILabel alloc] initWithFrame:frame];
strikethrough.opaque = YES;
strikethrough.backgroundColor = [UIColor clearColor];
strikethrough.text = @"------------------------------------------------";
strikethrough.lineBreakMode = UILineBreakModeClip;
[cell addSubview:strikethrough];
}

提前致谢: - )

2 个答案:

答案 0 :(得分:2)

问题在于行CGRect frame = cell.textLabel.frame;
单元格的textLabel尚未布局,因此框架将为(0,0,0,0),并且您将看不到删除线标签。

你在下一个单元格中看到删除线的原因是因为那些是已经布局了textLabel的重用单元格。

我认为你有两种选择:
第一个选项,自己设置删除线框,你可以使用sizeWithFont来确定所需的宽度,字体应该是textFiled字体。稍微玩一下,找到正确的x偏移,这样就完全在textLabel上。

- (void)addStrikethrough:(UITableViewCell*)cell
{
    CGSize textLabelSize = [cell.textLabel.text sizeWithFont:[UIFont systemFontOfSize:20.0]];

    CGFloat cellHeight = cell.bounds.size.height;
    CGFloat strikethroughLabelHeight = 20.0;

    CGRect frame = CGRectMake(12, (cellHeight - strikethroughLabelHeight)/2, textLabelSize.width, strikethroughLabelHeight);
    UILabel *strikethrough = [[UILabel alloc] initWithFrame:frame];
    strikethrough.opaque = YES;
    strikethrough.backgroundColor = [UIColor clearColor];
    strikethrough.text = @"------------------------------------------------";
    strikethrough.lineBreakMode = UILineBreakModeClip;
    [cell.contentView addSubview:strikethrough];
}  

第二个选项是子类UITableViewCell并为其添加删除线标签 然后你可以在layoutSubviews方法中设置它的框架,你可以根据你的需要隐藏/取消隐藏这个标签......

答案 1 :(得分:1)

基于其重用标识符重用该单元。目前您只使用一个标识符,因此“没有子视图的单元格”与操作系统中的“具有子视图的单元格”相同。

尝试在开始时检查删除线条件,并在这种情况下发明新的重用标识符(例如StrikeIdentifier)。

这是一种做我想建议的方法:

Item *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
BOOL isStrike = ([[item hasStrikethrough] boolValue]);

static NSString *CellIdentifier = @"ItemCell";
static NSString *StrikeIdentifier = @"ItemCellStrike";

UITableViewCell *cell = (isStrike)
                        ? [tableView dequeueReusableCellWithIdentifier:StrikeIdentifier]
                        : [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell==nil) {
    if (isStrike) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:StrikeIdentifier];
        [self addStrikethrough:cell];
    } else {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
}

. . .