0

4行のグループ化されたtableViewがあります。2つのビュー間でどのように処理を行っているかについてかなり大規模なオーバーホールを行いましたが、reloadDataがおかしな動作をしています。1行のデータのみを更新します。(最後のもの)そして他のどれも。

viewDidAppearメソッド(reloadDataを呼び出す)で値を確認し、すべての値が更新されました。

コード..

 - (void)viewDidAppear:(BOOL)animated
{
   [super viewWillAppear:animated];
   // reload the table data
   [self.tableView reloadData];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{     
   // Set up the cell...
  static NSString *CellWithIdentifier = @"Cell";
  UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.textLabel.text = [_tableGroup.options objectAtIndex:rowcount];
    cell.tag = rowcount;
    rowcount++;

    //label for currently selected/saved setting
    _currentSetting = [[BaseLabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
    [_currentSetting setFont:[UIFont systemFontOfSize:14]];
    _currentSetting.backgroundColor = [UIColor clearColor];
    _currentSetting.textColor = [UIColor blueColor];
    _currentSetting.textAlignment = NSTextAlignmentRight;
}

if (cell.tag == 0) {
    _currentSetting.text = [NSString stringWithFormat:@"%@ mi",[settings.val1 stringValue]];

}
else if(cell.tag == 1)
{
    _currentSetting.text = [NSString stringWithFormat:@"%@ items",[settings.val2 stringValue]];

}
else if(cell.tag == 2) 
{
    _currentSetting.text = [NSString stringWithFormat:@"%@ items",[settings.val3 stringValue]];

}

[cell.contentView addSubview:_currentSetting];

return cell;
}

NSLogを使用しましたが、reloadDataですべてが正常に呼び出されていますが、セルのラベルは変更されていません。なんで?

4

3 に答える 3

3

問題 1: cellForRowAtIndexPath は、既存のセルを取得するか、セルを作成してサブビューを追加する (セルを作成する場合のみ) ことによって、セルを返す必要があります。既存のセルがある場合は、サブビューが追加されていると想定できるので、それを探すだけです。だから、このように動作します...

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

    static NSString *CellWithIdentifier = @"Cell";
    BaseLabel *_currentSetting;

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellWithIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        // new cell, so add a label
        _currentSetting = [[BaseLabel alloc] initWithFrame:CGRectMake(160, 8, 115, 25)];
        [_currentSetting setFont:[UIFont systemFontOfSize:14]];
        _currentSetting.backgroundColor = [UIColor clearColor];
        _currentSetting.textColor = [UIColor blueColor];
        _currentSetting.textAlignment = NSTextAlignmentRight;
        _currentSetting.tag = 128;
        [cell.contentView addSubview:_currentSetting];
    } else {
        // existing cell so find the label
        _currentSetting = (BaseLabel *)[cell viewWithTag:128];
    }

問題 2: これで、セルの準備が整い、ラベル サブビューへのハンドルができました。どのように構成する必要がありますか? 唯一の賢明な方法は、indexPath に基づいてモデルを調べることです。

ここでは、モデルを理解しないとあまり役に立ちませんが、一般的な考え方は次のとおりです。

    // say my model is an array of N arrays, one for each section, I would do this
    NSArray *sectionModel = [self.mainModel objectAtIndex:indexPath.section];
    id *modelElement = [sectionModel objectAtIndex:indexPath.row];

    // now configure the cell based on modelElement
    _currentSetting.text = [modelElement someStringAttributeOfMyModel];
    return cell;
}
于 2013-02-01T20:59:14.647 に答える
3

ここで見られる主な問題は次のとおりです。

cell.tag = rowcount;
rowcount++;

cell.tag はif (cell == nil)内に存在してはならず、むしろそれを取り除く必要があります。代わりに、cell.tag をチェックして currentSettingText を設定するべきではありません。indexPath.row を使用する必要があります。

また、各viewDidAppearで、テーブルをリロードすると、cellForRowAtIndexPathが呼び出されます。これは、rowCountをインクリメントしているため、毎回cell.tagをどこでリセットしていますか?

于 2013-02-01T20:47:34.790 に答える
1

非常に奇妙なviewWillAppear呼び出しを見落とすことができますが、興味深いのは、メソッドでパラメーターをまったく使用しないことです。このパラメーターは、生成しているセルを確認する唯一の方法であるため、実質的に任意の結果を得ることができ、セルをランダムに並べ替えることができます。Aはそれらをもう一度シャッフルします。viewDidAppearindexPathreloadData

のみが増加すると、rowcountすぐにどのcell.tag ==比較も true と評価されなくなります。

ところで、コードは既存のセルにサブビューを追加しています。つまり、何度かリロードしたりスクロールしたりした後、セルには多くのラベルが表示されます。セルに最後に追加されたラベルをインスタンス変数に保存し、テキストを変更してから別のセルに移動する理由...それは謎です。

あなたのコードには意味がありません!

于 2013-02-01T20:49:46.617 に答える