web-dev-qa-db-ja.com

選択されたときに選択されたUItableViewCellが青のままになる

ユーザーがUITableViewの行を選択した後にビューをプッシュすると、行が青く強調表示され、新しいビューが表示されます。それはいいです。しかし、「戻る」とき、行はまだ青で強調表示されています。ここに私のdidSelectRowAtIndexPathコードがあります。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:nil];
    [[self navigationController] pushViewController:controller animated:YES];
    [controller release], controller = nil; 
}

私は何を間違えていますか?

55
cannyboy

上記の回答が指摘しているように、行を明示的に選択解除する必要があります。これを行うには、2つのオプションがあります。 1つ目は、選択後すぐに行を選択解除することです。

_- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
_

それはうまく機能しますが、代替があり、UITableViewControllerが取るアプローチは、行を選択したままにし、ビューが再表示されたときに選択を解除することです(押しているコントローラーがポップされた後)スタックから)。

これには、ユーザーが戻ったときに以前の選択を垣間見ることができるため、以前に選択したものを見ることができるというわずかな利点があります。

これを実装するには、viewWillAppearをオーバーライドするだけです。

_- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
_

私が言ったように、これはUITableViewControllerの_viewWillAppear:_の実装のデフォルトがUITableViewControllerを使用していてnotこの動作は、クラスの_viewDidAppear:_でsuper実装を呼び出していることを確認する必要があります。

更新(2013年10月30日):まあ、これは一般的な答えです! Benがコメントで正しく指摘しているように、UITableViewControllerは実際に_viewWillAppear:_ではなく_viewDidAppear:_でこれを行います。これが正しいタイミングです。さらに、UITableViewControllerのclearsSelectionOnViewWillAppearプロパティを使用して、この動作をオンまたはオフにします。これを反映するために、上記の回答を修正しました。

171
Luke Redpath

UITableViewControllerにはclearsSelectionOnViewWillAppearというBOOLプロパティがあり、これはまさにあなたが望むことをします。

デフォルトではYESに設定されていますが、独自のviewWillAppear:メソッドを実装することで、(誤って)このプロパティを無効にできることに気付きました。これは、[UITableViewController viewWillAppear:]の間に選択解除が発生するためだと思います。

解決策は簡単です。そのメソッドのバージョンのどこかでviewWillAppear:のスーパーバージョンを呼び出すだけです。

- (void)viewWillAppear:(BOOL)animated {
  // Your custom code.
  [super viewWillAppear:animated];
}

Appleは、ビュー{Did、Will} {A、Disa} ppearメソッドのスーパーバージョンをオーバーライドする場合は常に呼び出すことをお勧めします。

参考文献

11
Tyler

選択を解除する必要があります。

[tableView deselectRowAtIndexPath:indexPath animated:YES];

7
pkananen

コントローラーがUITableViewControllerに基づいている場合、この機能は無料で入手できます。しかし、私はしばしばUIViewControllerをnoで使用することになりました。 UITableViewに加えて他のコントロールの場合、その場合は、viewWillAppearをオーバーライドして

-(void) viewWillAppear:(BOOL)animated{
    // Unselect the selected row if any
    NSIndexPath*    selection = [devListTableview indexPathForSelectedRow];
    if (selection){
        [tableview deselectRowAtIndexPath:selection animated:YES];
    }
}
4
palaniraja

[tableView deselectRowAtIndexPath:indexPath animated:YES]を呼び出すだけです。

3
Ben Gottlieb

UITableViewControllerのデフォルトの動作では、ユーザーが詳細ビューから戻ったときに行の選択が解除されます。ルークからの回答は問題ありませんが、その理由を指摘したいと思います。

1-ゼロから作成したときのようにUITableViewControllerがある場合、すべてのデフォルトの動作になります。

2-状況1で-viewWillAppearまたは-viewDidAppearを追加すると、標準の動作が上書きされます。戻り時に行の選択を解除したい場合は、superを明示的に言って、いつものように自分で行の選択を解除したいことを宣言する必要があります。これを実現するには、ルークが言うように、次のように[super viewWillAppear:animated]または[super viewDidAppear:animated]を呼び出す必要があります。

-(void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    // Here goes all of your stuff
}
2
Ruben Marin

別の解決策は、viewWillAppearでUITableViewのreloadDataを呼び出すことです。

0
Andy A