7

複数の成分を選択できる複数選択リストを作成しました。

私のテーブルビューでは、Ingredient のリスト プロパティに基づいて、セルを有効または無効にすることができます。Ingredient's list プロパティが設定されている場合、セルは無効になります。

ただし、セルを再利用すると、期待どおりに表示されません。以下の画像は、私よりも効果的に問題を説明しています。

(有効にすべきではない材料は、ケーキのアイシング、コンデンス ミルク、コーンフラワーです。)

  1. 最初の画像は、期待どおりに無効化され、注釈が付けられた 3 つの Ingredients を示しています。

  2. ただし、2 番目の画像では、下にスクロールすると、一部の成分が無効になっていることがわかります (ただし、それらを選択することはでき、それらは完全に相互作用します)。

  3. 3 番目の画像は、スクロールして一番上まで戻った後のリストを示しています。一部の材料はグレー表示されており、対話/選択できないにもかかわらず、コーンフラワーが有効として表示されていることに注意してください。

問題は、セルの再利用に関するものです。セルは再使用時に「リセット」されていないようで、「古い」外観の一部が保持されています。

以下は のコードcellForRowAtIndexPath:です。ここに問題があると確信しています (ただし、何が問題なのかはわかりません)。

- (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];
    }    

    // Fetches the corresponding Ingredient from the ingredientArray
    Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already in your Lardr";
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already on your Shopping List";
    }
    else
    {
        cell.userInteractionEnabled = YES;
        cell.detailTextLabel.text = @"";
    }

    // Add a checkmark accessory to the cell if the ingredient is on the selectedIngredients array
    if ([self.selectedIngredients containsObject:ingredient])
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    cell.textLabel.text = ingredient.name;

    return cell;
}

私はこれを理解しようとして頭がいっぱいで、リモートでさえ関連しているSOの質問をすべて読みましたが、役に立ちませんでした。どうしたの?!


私の論理では、if ステートメントを介した実行パスに関係なく、セルごとに textLabel、detailTextLabel、userInteractionEnabled、および accessoriesType プロパティが設定されているため、再利用した後でもセルが正しく表示されない理由がわかりません。


編集:問題の根本を突き止めようとして、対応する成分を取得する行のすぐ上に次の行を追加して、セルをデフォルトに「リセット」しようとしましたが、役に立ちませんでした。

cell.userInteractionEnabled = YES;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
cell.accessoryType = UITableViewAccessoryNone;

ただし、興味深いのは完全に非論理的です - 次の行cell.textLabel.text = ingredient.nameを の行のすぐ下に移動するIngredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];と、 userInteraction がさらに下に設定されていても (そして関連するセルは期待どおりに無効になっています)、どのセルにもスタイリングはまったく適用されません。 .

私が考えているのは、セルのプロパティが設定される順序は重要ですか? いけないのはわかっていますが、上記を踏まえて見た目が変わります。


更新: 問題を解決しました。以下の私の答えを見てください。

4

4 に答える 4

2

willDisplayCellでセルの色を明示的に設定します

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

 Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else
    {
        cell.textLabel.textColor = [UIColor blackColor];
    }

}
于 2013-04-03T10:32:08.800 に答える
2

私は問題を解決しました。問題は、セルのテキストを設定する前に userInteractionEnabled を設定していたことです (コメントの Carl Veazey からのリンクに感謝します)。

userInteractionEnabled プロパティを調整する前に、セルのテキストを設定することで問題を修正しました。ただし、(セルが無効になっていても) セルにスタイルは適用されませんでした。したがって、セルの textColor を設定して、セルのスタイルを手動で設定する必要がありました。以下は、コメント付きの調整済みコードです。

- (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];
    } 

    // Fetches the relevent ingredient from the ingredientArray
    Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];
    cell.textLabel.text = ingredient.name; // Moved this line before setting userInteractionEnabled

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already in your Lardr";
        cell.textLabel.textColor = [UIColor grayColor]; // Update the color accordingly
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already on your Shopping List";
        cell.textLabel.textColor = [UIColor grayColor];
    }
    else
    {
        cell.userInteractionEnabled = YES;
        cell.detailTextLabel.text = @"";
        cell.textLabel.textColor = [UIColor blackColor];
    }

    // Add a checkmark accessory to the cell if the ingredient is on the selectedIngredients array
    if ([self.selectedIngredients containsObject:ingredient])
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    return cell;
}

明らかに、セルのプロパティを設定する順序は無関係であるべきなので、これはバグであると確信しています。これが同じ問題に遭遇した他の人に役立つことを願っています.

于 2013-04-03T16:48:20.897 に答える
0

テーブルビューで選択したセルのリストを維持し、セルを再利用しながら、セルが既に選択リストにあることを確認してください。はいの場合は、そこでカスタマイズを行ってください。このようにしてみてください。

宣言

 TableViewCell *_selectedCell; 

行をカスタマイズして、選択したセルを保存し、選択リストを維持します。

_selectedCell = (TableViewCell*)[self.ItemTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:rowIndex inSection:0]];

cellForRowAtIndexPath で、現在のセルが

if(_selectedCell)
        [cell setBackgroundColor:[UIColor whiteColor]];// Customize the cell 
于 2013-04-03T03:53:02.050 に答える
0

ストーリーボードのテーブル ビュー コントローラーで次のコードを使用すると、すべて正常に動作しました。ストーリーボードを使用していないときにデフォルトで表示されるテーブル ビューには、いくつかのバグがあるようです。

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

    // Fetches the corresponding Ingredient from the ingredientArray
    Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already in your Lardr";
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already on your Shopping List";
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else
    {
        cell.userInteractionEnabled = YES;
        cell.detailTextLabel.text = @"";
        cell.textLabel.textColor = [UIColor blackColor];
    }

    if ([self.selectedIngredients containsObject:ingredient])
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    cell.textLabel.text = ingredient.name;

    return cell;
}

dequeueReusableCellWithIdentifier: の代わりに dequeueReusableCellWithIdentifier:forIndexPath: を使用し、if 句を削除していることに注意してください。これはあなたの問題とは何の関係もありませんが、ストーリーボードのテーブル ビューに対してこれを行う最新の方法です。

于 2013-04-03T03:54:14.860 に答える