2012-02-13 7 views
4

申し訳ありません。iOS - ループスルーセルとデータの取得

私はが単一のXiBペン先から引き出された細胞からのセットアップを持っています。ペン先にオン/オフスイッチを作成しました。スイッチの状態をviewWillDisappearに保存しようとしています。 (正確には6細胞)。

どのようにすべてのセルをループしてこの情報を保存できますか?

私は1つのセルのための情報を得るために、私のUIViewControllerでこれを試してみました:

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 

    UITableView *tv = (UITableView *)self.view; 
    UITableViewCell *tvc = [tv cellForRowAtIndexPath:0]; 

} 

それはエラー「プログラムが信号受信: 『私を与えます。EXC_BAD_INSTRUCTION』を

私はこれを実現するにはどうすればよい

+0

なぜ 'tv'を宣言しますか? 'self.tableView'を使用できませんか? – Novarg

+1

スイッチの状態をセルに保存しないでください。 – NeverBe

+0

私はNeverBeに同意します - 記述したようにしないでください(小さなテーブルがあり、再利用できないとセルを定義している場合を除いて)。テーブルビューを使用するための推奨される方法は、別の*モデル*で状態を維持することです。*ユーザーが変更を加えると、各フィールドの 'editDidEnd'メソッドまたは同様のメソッドにハンドラーを追加することで、そのモデルを変更*で更新します。 「完了」をクリックすると、カスタムモデルのデータが確認されます。表示されたフィールドは必要ありません。 – ToolmakerSteve

答えて

11

有効なNSIndexPathcellForRowAtIndexPath:に渡す必要があります。 0を使用しました。これはindexPathを意味しません。

UITableViewCell *tvc = [tv cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 

しかし

あなたはこのようなものを使用する必要があります。これをしないでください。 UITableViewCellに状態を保存しないでください。
スイッチが状態を変更したときにデータソースを更新します。

UITableViewDataSourceメソッドを実装していれば、tableViewがセルを再利用する理由がわかります。つまり、細胞が再利用されると、細胞の状態は消滅します。

あなたのアプローチは6つのセルで有効です。しかし、それは9細胞では失敗するでしょう。
最初のセルを画面からスクロールすると、おそらく失敗することもあります。あなたの代わりにそれを行うべきかをお見せするために(あなたは、彼らが必要なところARCはreleaseを追加使用しない場合)


私は、迅速なデモを書いた:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.dataSource = [NSMutableArray arrayWithCapacity:6]; 
    for (NSInteger i = 0; i < 6; i++) { 
     [self.dataSource addObject:[NSNumber numberWithBool:YES]]; 
    } 
} 

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
     UISwitch *aSwitch = [[UISwitch alloc] init]; 
     [aSwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; 
     cell.accessoryView = aSwitch; 
    } 
    UISwitch *aSwitch = (UISwitch *)cell.accessoryView; 
    aSwitch.on = [[self.dataSource objectAtIndex:indexPath.row] boolValue]; 
    /* configure cell */ 
    return cell; 
} 

- (IBAction)switchChanged:(UISwitch *)sender 
{ 
// UITableViewCell *cell = (UITableViewCell *)[sender superview]; 
// NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 
    CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView]; 
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView]; 
    [self.dataSource replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:sender.on]]; 
} 

あなたはそれが非常にではありません見てセルに状態を格納しないように複雑になる:-)

+0

+1です。あなたのアプローチは、セル内のテキストフィールドにも適用できますか?たとえば、テキストフィールドでセルを作成すると、 '[cell.textfield addTarget:self action:@selector(updateField :) forControlEvents:UIControlEventValueChanged];'と言うことができます。これにより、値が変更されるたびに対応するモデルを更新することができます。これはオーバーヘッドを導入しますか?テキストフィールドの代理人(例えばdidEndEditing)に登録してモデルを更新する方が簡単でしょうか?ありがとう。 –

+0

ありがとう、マティアス。私はマークされた状態をセルに保存するロジックを書いていましたが、データソースをリフレッシュするのをやめましたが、セルがスクロールしてリロードされた場合、その状態を失ってしまいました。 –

1

お客様の方法の最後まで[super viewDidDisappear:animated];を移動することが問題の解決に最も適切な方法ですが、それでも問題が解決しない場合は、ロジックをviewWillDisappear:animated:に移動してください。

これに対処するより良い方法は、ビューから現在の状態を読み取らないことです。むしろ、表示は各更新時にモデルに状態を渡す必要があります。この方法では、ビューの状態から完全に独立して、モデルから現在の状態を収穫することができます。

+0

セル内のさまざまな選択肢ではなく、ビューを保存すると言っていますか? – Romes

+0

@Romesいいえ、私は[モデルオブジェクト]について話しています(https://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/ModelObject.html#//apple_ref/doc/ uid/TP40008195-CH31-SW1)をMVC実装で使用します。 *あなたのシステムが最新の状態になっていなければなりません。ビューが完全になくなった時間を含め、いつでもこのモデルオブジェクトを取得して保存することができます。返信は – dasblinkenlight

関連する問題