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;
The cell's textLabel の行がまだレイアウトされていないため、フレームが (0,0,0,0) になり、取り消し線ラベルが表示されないことです。

次のセルに取り消し線が表示される理由は、それらのセルが再利用され、textLabel が既に配置されているためです。

私が見ているように、2つのオプションがあります。
最初のオプションは、取り消し線フレームを自分で設定します.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];
}  

2 番目のオプションは、UITableViewCell をサブクラス化し、それに取り消し線ラベルを追加することです。
次に、layoutSubviews メソッドでそのフレームを設定し、必要に応じてこのラベルを非表示/非表示にできます...

于 2012-07-23T08:21:59.437 に答える
1

セルは、その再利用識別子に基づいて再利用されます。現在、1 つの識別子しか使用していないため、「サブビューのないセル」は OS には「サブビューのあるセル」と同じように見えます。

最初に取り消し線の状態を確認し、StrikeIdentifierその場合は新しい再利用識別子 (例: ) を考えてみてください。

私が提案していることを行う1つのアプローチを次に示します。

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 に答える