web-dev-qa-db-ja.com

UITableViewCellが強調表示されたままになるのはなぜですか?

テーブルビューセルがタッチされた後に強調表示されたままになる原因は何ですか?セルをクリックすると、詳細ビ​​ューがプッシュされても強調表示されたままになります。詳細ビューをポップしても、セルは引き続き強調表示されます。

139
4thSpace

didSelectRowAtIndexPathで、deselectRowAtIndexPathを呼び出してセルの選択を解除する必要があります。

したがって、didSelectRowAtIndexPathで他に何をしていても、deselectRowAtIndexPathを呼び出すだけです。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 // Do some stuff when the row is selected
 [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
254
paulthenerd

最もクリーンな方法はviewWillAppearにあります:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Unselect the selected row if any
    NSIndexPath*    selection = [self.tableView indexPathForSelectedRow];
    if (selection) {
        [self.tableView deselectRowAtIndexPath:selection animated:YES];
    }
}

これにより、コントローラーに戻るときに、選択範囲がフェードアウトするアニメーションが表示されます。

http://forums.macrumors.com/showthread.php?t=577677 から取得

Swiftバージョン

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // deselect the selected row if any
    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRowNotNill = selectedRow {
        tableView.deselectRow(at: selectedRowNotNill, animated: true)
    }
}
58
Danail

-(void)viewWillAppear:(BOOL)animatedをサブクラス化しましたか?カスタムメソッドで[super viewWillAppear:animated];を呼び出さない場合、選択したUITableViewCellは選択解除されません。

20
HansPinckaers

Swiftユーザーの場合、これをコードに追加します。

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

Swiftを除いて、paulthenerdの答えです。

18

Swift 3ソリューション

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
9
Oscar

UITableViewCellを使用している場合は、次の行をコメントしてください

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

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

}

お役に立てれば。

7
Shantanu

Swift 4で更新

以前の回答にも基づいたいくつかの実験の後、2つの方法で最適な動作を実現できるという結論に達しました(実際にはほとんど同じです)。

// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: false)
}

// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        tableView.deselectRow(at: selectedRow, animated: false)
    }
}

私は個人的に最初のソリューションを採用していますが、それは単に簡潔だからです。別の可能性は、tableViewに戻るときに少しアニメーションが必要な場合、viewWillAppearを使用することです。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        _view.tableView.deselectRow(at: selectedRow, animated: true)
    }
}

最後になりましたが、UITableViewControllerを使用している場合は、プロパティ clearsSelectionOnViewWillAppear を利用することもできます。

Kendall Helmstetter Gelnerがコメントで説明している動作を取得するには、おそらくdeselectRowAtIndexPathではなく、コントローラーのclearsSelectionOnViewWillAppearプロパティが必要です。おそらくこれは偶然にYESに設定されたのでしょうか?

新しいUITableViewControllerサブクラスについては、デフォルトのAppleテンプレートのコメントを参照してください。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
}
3
Dave Teare

ドリルダウンアプリケーションでもこの問題が発生していました。 VCと呼ばれるViewControllerが別のViewControllerをプッシュした後に戻ると、VCで選択されたセルが強調表示されたままになります。私のアプリでは、VC =ドリルダウンの2番目のレベル(3つのレベルのうち)を処理します。

私の場合の問題は、VCがUIViewController(TableViewを含むViewを含む)だったということです。代わりにVC UITableViewController( TableView)。UITableViewControllerクラスは、Pushから戻った後、テーブルセルのハイライト解除を自動的に処理します。投稿に対する2番目の回答「 tableViewのdeselectRowAtIndexPathの問題 」は、この問題に対するより完全な回答を提供します。

XCodeで「ナビゲーションベースのアプリ」としてアプリを作成したとき、結果のルートビューコントローラーは既にサブクラスUITableViewControllerに作成されていたため、ルートビューコントローラーでは問題は発生しませんでした。

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
1
Mob

これらのいずれも機能しない場合は、次の回避策を検討してください。

巻き戻しセグエを使用して呼び出す:

@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
    if let index = tableView.indexPathForSelectedRow {
        tableView.deselectRowAtIndexPath(index, animated: true)
    }
}

どうしてですか?主に、適切なタイミングで実行する選択解除コードの取得に問題がある場合。 viewWillAppearで動作しないので問題があったので、巻き戻しはずっとうまくいきました。

手順:

  1. 巻き戻しセグエを(または上から貼り付けて)1番目に書きますVC(テーブルのあるもの))
  2. 2番目のVCに移動します。 VC=)を閉じるために使用している[キャンセル]/[完了]/[その他]ボタンからControlキーを押しながらドラッグし、上部の[終了]アイコンにドラッグします。
  3. ステップ1で作成した巻き戻しセグエを選択します

    幸運を。

1
Dave G

私はCoreDataを使用しているので、私のために働いたコードは、Swiftのさまざまな答えからのアイデアの組み合わせでした:

override func viewDidAppear(_ animated: Bool) {
    if let testSelected = yourTable.indexPathForSelectedRow {
        yourTable.deselectRow(at: testSelected, animated: true)
    }
    super.viewDidAppear(true)
}
1
Yewzr

セルに触れた後にセルが強調表示されたままの場合、UITabelViewメソッドを呼び出すことができます。

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

`[tableView deselectRowAtIndexPath:indexPath animated:YES];`   

}

または、次の方法を使用し、要件に応じて変更できます。

// MARK:UITableViewDelegate

func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
  if let cell = tableView.cellForRowAtIndexPath(indexPath) {
     cell.backgroundColor = UIColor.greenColor()
  }
}

func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
  if let cell = tableView.cellForRowAtIndexPath(indexPath) {
     cell.backgroundColor = UIColor.blackColor()
  }
} 
0
Varsha Shivhare

Xcode 10、Swift 4

これと同じ問題が発生し、tableViewControllerの下部にあるviewWillAppearへの空の呼び出しを残していることがわかりました。空のオーバーライド関数を削除すると、tableViewビューに戻っても行は強調表示されなくなりました。

問題機能

override func viewWillAppear(_ animated: Bool) {
  // need to remove this function if not being used.
}

空の関数を削除することで問題が解決しました。

0
Robac

For Swift 3:私はそれをviewDidDisappearで使用することを好むだろう

定義:-

    var selectedIndexPath = IndexPath()

ViewDidDisappear:-

    override func viewDidDisappear(_ animated: Bool) {
    yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}

DidSelectRowAtIndexPath:-

    func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
    selectedIndexPath = indexPath
}
0
Irshad Qureshi

私は長い間同じ問題を抱えてきたので、他の誰かが苦労している場合に備えて:

-tableView: cellForRowAtIndexPath:そして、セルを作成しているか、「再利用識別子」を使用しているかを確認します。後者の場合、IBのテーブルにその識別子のセルがあることを確認してください。再利用識別子を使用していない場合は、行ごとに新しいセルを作成してください。

これにより、表に表示される「フェード選択行」が期待できるようになります。

0
LearningAsIGo

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

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

   // Just comment This line of code
   // [super setSelected:selected animated:animated];        
}
0
sunny