0

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

这是我的 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];
}

提前致谢 :-)

4

2 回答 2

3

问题在于 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 方法中设置它的框架,你可以根据你的需要隐藏/取消隐藏这个标签......

于 2012-07-23T08:21:59.437 回答
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];
    }
}

. . .
于 2012-07-23T01:49:49.567 回答