1

以下に表示される tableView には、 が含まれていますlabelsubViewセルごとに追加されます。

プログラムを初めて実行すると、画面に表示されるセルに正しいテキストが表示されます。しかし、表をスクロールすると、ラベルのテキストが混同され始めます。私が理解していることから、セルが作成されると、あるセルのラベルが別のセルの上に重ねられます。これは、後の 2 つのスクリーンショットに示されています。スクロールするたびに、異なるセルが他のセルの上に重ねられます。(だから決まったパターンはありません。)どのセルが画面から出て、どのセルが入るかを観察して問題を理解しようとしました。この情報をセルのラベルと関連付けようとしましたが、理解できません。

この不一致の原因を理解していただけるよう、ご協力をお願いいたします。

ありがとうございます!

ここに画像の説明を入力

私のコードの関連セクションは次のとおりです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    NSLog(@"s = %d, r = %d", indexPath.section, indexPath.row);

    if (indexPath.section == 0)
    {
        switch(indexPath.row)
        {
            case 0:
            [cell addSubview:classA];
            break;

            case 1:
            [cell addSubview:classB];
            break;

        case 2:
            [cell addSubview:classC];
            break;

        case 3:
            [cell addSubview:classD];
            break;

        case 4:
            [cell addSubview:classE];
            break;

        default:
            break;
    }
}

if(indexPath.section == 1)
{
    switch(indexPath.row)
    {
        case 0:
            [cell addSubview:classF];
            break;

        case 1:
            [cell addSubview:classG];
            break;

        case 2:
            [cell addSubview:classH];
            break;

        default:
            break;
    }
}

if(indexPath.section == 2)
{
    switch (indexPath.row)
    {
        case 0:
            [cell addSubview:classI];
            break;

        case 1:
            [cell addSubview:classJ];
            break;

        case 2:
            [cell addSubview:classK];
            break;

        default:
            break;
    }
}

return cell;
}
4

3 に答える 3

3

テーブル ビューのセルは再利用されます: 上下にスクロールするdequeueReusableCellWithIdentifierと、別の (現在は非表示になっている) 行で以前に使用されたセルが返される場合があります。

その場合、セルにはすでにサブビューの 1 つが含まれており、さらにサブビューを追加します。

于 2012-11-19T19:32:56.583 に答える
1

その理由は、dequeueReusableCellWithIdentifierセルを再利用するために使用しているためです。したがって、スクロールしているときに、表示領域から外れるセルは、現在表示されているセルに再利用されます。

これらのセルにはすでになどのラベルが追加されclassBており、その後削除されていないため、その後、classI再利用された同じセルになどのラベルを追加すると、このラベルの上に描画されます。これらのラベルは背景色がクリア色に設定されているため、その後ろに描かれたラベルも表示され、重なり感があります。

スクリーンショットによると、すべてのセルが同じように見え、セルを で確実に再利用できますdequeueReusableCellWithIdentifier。では、ラベルを外部で作成するロジックを変更してcellForRowAtIndexPath、代わりにcell.TextLabel.text = @"Class B";、このメソッド内の対応する if 条件などで使用しないでください。

コードは次のようになります。

if (indexPath.section == 0)
    {
        switch(indexPath.row)
        {
            case 0:
            cell.textLabel = [self createLabelForRow:indexPath.row section:indexPath.section];
//or if it is jut a simple label, you can just set font and other properties in cell.textLabel directly
            cell.textLabel.text = @"Class A";
            break;

更新:dequeueReusableCellWithIdentifierすべてのセルが静的である場合の再利用にはあまり適していない修正があります。しかし、これは推奨される方法ではありません。

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

  NSString *CellIdentifier = [NSString stringWithFormat:@"CellForRow%dSection%d",indexPath.row, indexPath.section];
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil)
   { 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
   }

  //or try this

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
  if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
    }

Update2:上記の問題に直面している場合は、これを試してください。私の最初のアプローチを使用して、次のことを行います。

if (indexPath.section == 0)
    {
        switch(indexPath.row)
        {
            case 0:
            cell.textLabel = [self createLabelForRow:indexPath.row section:indexPath.section];

            // or do the following,

            [self removeAllTextFieldsFromCell:cell];
            UITextField *aTextField = [self createTextFieldForRow:indexPath.row section:indexPath.section];
            [cell.contentView addSubview:aTextField];
         }

メソッドではremoveAllTextFieldsFromCell:、RA の提案を使用します。

例:-

- (void)removeAllTextFieldsFromCell:(UITableViewCell *)cell {

    for (UITextField *textField in cell.contentViews.subViews) {
        [textField removeFromSuperView];
    }
}

または単に使用する、

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    NSLog(@"s = %d, r = %d", indexPath.section, indexPath.row);

    //if it is all textfields in the cell, it will look like,
    [self removeAllTextFieldsFromCell:cell];
    UITextField *aTextField = [self createTextFieldForRow:indexPath.row section:indexPath.section];
    [cell.contentView addSubview:aTextField];

    return cell;
}
于 2012-11-19T19:33:27.107 に答える
1

あなたがコメントで言ったように、あなたはあなたの細胞からするtextfield必要があります。remove the old textFieldこのコードを の前に追加できますif statement for indexPath.section checking

for (UITextField *textField in cell.contentViews.subViews) {
    [textField removeFromSuperView];
}
于 2012-11-19T19:43:40.863 に答える