web-dev-qa-db-ja.com

iPhone UITableViewセルが選択されたままになる

uITableViewで、タッチした後にセルが選択されたままになることがあります。まれにしか発生しないため、問題を再現できません。

ヒントはありますか?多分それはtableViewの不適切なリリースと関係がありますか?

    - (void)tableView:(UITableView *)tableView 
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath{   
    NSUInteger row = [indexPath row];

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

switch (row) {
    case 0:
        FruitViewController *fruitController = [FruitViewController alloc];
        [fruitController retain];
        [fruitController initWithNibName:@"FruitView" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:fruitController animated:YES];
        [fruitController release];
        break;
    case 1: 
        CerealsViewController *cerealsController = [CerealsViewController alloc];
        [cerealsController retain];
        [cerealsController initWithNibName:@"CerealsView" bundle:[NSBundle mainBundle]];
        [self.navigationController pushViewController:cerealsController animated:YES];
        [cerealsController release];
        break;
    default:
        break;   
}
   }
45
Stefan

この問題が発生している理由をお話しすることはできませんが、修正のためのいくつかの提案を以下に示します。

Apple HIGによると、スタックにプッシュされたばかりのビューコントローラーから戻るまで、選択は消えないはずです。コントローラーが単なるUITableViewControllerの場合、ビューに戻ったときに自動的に選択を解除する必要があります。そうでない場合は、追加

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

ビューコントローラのどこかに。

クリックしても別のビューに移動せず、実際に選択しても何もしない行がある場合、それらは選択可能であってはならないので、

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath

また、行を選択してはならない場合はnilを返します。

98
Ed Marty

考えられる原因の1つは、UITableViewControllerを拡張するコントローラーで-viewWillAppear:animated:を呼び出さずに[super viewWillAppear]をオーバーライドすることです。 [super viewWillAppear:animated]メソッドの先頭に-viewWillAppearを追加すると、問題が解決する場合があります。

21
Fiid

「Ed Marty」の答えを拡張するために、見た目が良いと思ったので、代わりに「viewWillDisappear」メソッドに選択解除を追加することにしました。

これに加えて、(UITableViewControllerではなく)通常のUIViewControllerでUITableViewを使用していたため、tableView変数を使用できませんでした。これを克服するために、ビューコントローラーのヘッダーファイルにtableViewプロパティを追加しました(そしてXIBファイルに実際のテーブルビューをプロパティに接続しました)...

@property (nonatomic,retain) IBOutlet UITableView *tableView

...そしてビューコントローラの実装では、プロパティを配線し、次のように選択解除を実行しました。

@synthesize tableView

- (void) viewWillDisappear:(BOOL)animated {
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
    [super viewWillDisappear:animated];
}
11
Oliver Pearmain

UITableViewControllerを使用している場合は、以下を使用できます。

self.clearsSelectionOnViewWillAppear = YES;
8
Pach

私の場合、didSelectRowAtIndexPathの最後にあるセルの選択を解除します。

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Do smth here. segue ..etc

    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
}
4
helloiloveit

このメソッドをUITableViewCellクラスで使用します

(void)setSelected:(BOOL)selected animated:(BOOL)animated {

// Just comment This line of code

// [super setSelected:selected animated:animated];

}

または、didSelectRowAtIndexPathメソッドでこのコードを試すこともできます

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

//行が選択されたときに何らかの処理を行います

[tableView deselectRowAtIndexPath:indexPath animated:YES];

}

0
sunny

テーブルの管理方法を習得すると、この問題の解決には約2秒かかります。

セルが画面外にスクロールされるとすぐに、セルのフォーマットが失われます。テーブルは、他のセルを非表示にし、ユーザーがスクロールして戻ったときにセルを再作成することにより、メモリ使用量を最小限に抑えます。

テーブルデータの再読み込みなども、その時点で画面上のセルにのみ適用されます。つまり、cellForRowAtIndexPathは、ユーザーがボタンをクリックしたりビューコントローラを離れたりすることなく、同じセルを5回作成する可能性があります。したがって、すべてのフォーマットをリロードするように設定します。次のようなものをcellForRowAtIndexPathに追加します。

    if arrayOf_SelectedCells.contains(indexPath) {
        setup_Selected(cell)
        //Where setup_Selected is a custom function to apply formatt
    } else {
        setup_Unselected(cell)
    }
0
Dave G