2012-01-24 6 views
0

UITableViewためのコードですが、私は(あまりにも迷惑)不気味その振る舞いをスクロールするとき...この問題はreuseIdentifierによるものです....しかし、解決する方法を知らない...私のUITableView cellForRowAtIndex for Single Selectionの問題点は何ですか?以下は

にする方法
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier]; 

    NSInteger imgTag = 1; 
    NSInteger lblTag = 2; 

    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 

     UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(2, 2, 52, 52)]; 
//  Image:[UIImage imageNamed:[self.glassType objectAtIndex:indexPath.row]]]; 
     imgView.tag = imgTag; 
     [cell.contentView addSubview:imgView]; 
     [imgView release]; 

     UILabel *lblName = [[UILabel alloc] initWithFrame:CGRectMake(60, cell.frame.size.height/4, 200, 21)]; 
//  lblName.text = [self.glassName objectAtIndex:indexPath.row]; 
     lblName.tag = lblTag; 
     [cell addSubview:lblName]; 
     [lblName release]; 
    } 

    NSInteger imgIndex = 2; 
    NSInteger lblIndex = 3; 

    ((UIImageView *)[cell viewWithTag:imgTag]).image = [[self.glassType objectAtIndex:indexPath.row] objectAtIndex:imgIndex]; 
    ((UILabel *)[cell viewWithTag:lblTag]).text = [[self.glassName objectAtIndex:indexPath.row] objectAtIndex:lblIndex]; 

    return cell; 
} 

- (void)tableView:(UITableView *)tableView1 didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView1 cellForRowAtIndexPath:indexPath]; 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
} 

インデックス時の行のセルで、スクロールしても一定になるようにする??? UITableViewで一度選択する方法も?

+0

あなたはタグ100以上を使用する必要があります – drct

答えて

7

答えは、 "if(cell == nil){..."句の外のテーブルセルにサブビューを追加しないでください。または、それらが再取得されたときに同じセルに繰り返し追加される-中古。

それを修正する方法のためのコードを含む、より詳細な説明については、この質問に対する私の答えを参照してください:

cellForRowAtIndexPath memory management

とすぐに、彼らは彼らのオフスクリーンスクロールするようなので、あなたはまた、テーブルのセルの状態を保存することはできませんリサイクルされ、テーブルの別のインデックスに再表示されます。テーブルセルの状態(アクセサリの種類など)を格納するためのモデルオブジェクトの配列を設定する必要があります。より詳細な説明は、この質問に対する私の答えで見つけることができます:

Looping through UITableViewCells of a UITableView

あなたが細胞にサブビューを追加すること、および同様のモデルオブジェクトの配列で、あなたの「チェックさ」状態を保存する方法を修正した場合cell.accessoryTypeを設定すると(セルがデキューされたときにリストアできるように)、行選択の方法が正しく行われます。

だからreturn cell;前に、あなたのtableView:cellForRowAtIndexPath:方法でこれを置く:

MyModelObject *object = [self.arrayOfModelObjects objectAtIndex:indexPath.row]; 
BOOL isChecked = object.checked; 
cell.accessoryType = isChecked? UITableViewCellAccessoryCheckmark: UITableViewCellAccessoryNone; 

そして、あなたのtableView: didSelectRowAtIndexPath:方法では、現在のロジックを排除し、それを置き換えます:

- (void)tableView:(UITableView *)tableView1 didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    for (int i = 0; i < [self.arrayOfModelObjects count]; i++) 
    { 
     MyModelObject *object = [self.arrayOfModelObjects objectAtIndex:i]; 
     object.checked = (i == indexPath.row); // only check the one we just tapped 
    } 

    //refresh table to update the accessory views for all rows 
    [tableView1 reloadData]; 
} 

明らかに置き換えます独自のモデルを実装したarrayOfModelObjectsこの目的のためにカスタムクラスを作成したくない場合は、boolを含むNSNumberオブジェクトの配列を使用できます。

+0

私の更新されたコードを見てください..それはまだwierdlyに動作します...私の画像はスクロールでランダムに行きます。私は**ブロックの中に私のコードを残しているが、まだ問題が残っている... – DShah

+1

@DShah彼の最初のリンクでニックの答えを読んだ?彼の答えを読んで、そのコードのモデルに従ってください。 **ヒント**タグの使い方と 'if(cell == nil){}'が終わるところを見てください。 – NJones

+0

ニック:ありがとうございました。@NJones:ありがとう...両方に+1 ... – DShah

1

リサイクルキューは、以前に作成されたセルが再利用する前にに保存されているプールのようなものです。たとえば、上にスクロールすると、セルが上に消えた時点でキューに格納され、下に表示されるセルで使用できるようになります。 OK ?

実際に実際に作成されたセルの数は、テーブル(ほとんどの場合3〜8)に表示できる最大同時セルです。つまり、最初のreloadDataでコードif (cell == nil)が実行され(多かれ少なかれ3〜8回)、テーブルに必要なセルのプールが作成されます。

セルで行ったすべてがそのまま保持され、デキュー時に再度表示されます。あなたのコードでは、if(cell == nil)ブロックの外ですべての行依存の設定を厳密に行う必要があります。同様に、if (cell == nil)ブロックの外側にサブビューを追加しないで、デキューされたセルをリセットするたびに追加する数千のサブビューを想像することができます。

ヒント:あなたは(空白に画像を設定したい)のセルを再利用する前にいくつかのカスタムのクリーンアップが必要な場合は、カスタムUITableviewCellクラスを作成し、prepareForReuseメソッドを実装することができます。

それは明確ですか?

0

常にviewDidLoadではなくviewWillAppearメソッドでtableViewをリロードしてください。

  • (ボイド)viewWillAppear:(BOOL)アニメーション{

    [self.tableView reloadData]。

    }

これは、すべての予期しないと迷惑な問題のほとんどを回避することができます。 :)

関連する問題