Bagaimana membatalkan pilihan sel UITableView yang dipilih?


212

Saya sedang mengerjakan proyek di mana saya harus memilih ulang sel tertentu.

Saya dapat memilih ulang sel menggunakan -willDisplayCell, tetapi saya tidak dapat membatalkan pilihan ketika pengguna mengklik sel lain.

- (void)tableView:(UITableView*)tableView 
        willDisplayCell:(UITableViewCell*)cell
        forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        [cell setSelected:YES];    
    } 
}

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

    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;
    [materialTable deselectRowAtIndexPath:indexpath1 animated:NO];
}

Bisakah kamu menolong?


11
Pertanyaan ini harus memiliki jawaban yang diterima
Titouan de Bailleul

Jawaban:


408

gunakan kode ini

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
 {
    //Change the selected background view of the cell.
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
 }

Swift 3.0:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Change the selected background view of the cell.
    tableView.deselectRow(at: indexPath, animated: true)
}

1
Ada didDeselectRowAtIndexPath untuk digunakan untuk membatalkan pilihan yang sebelumnya.
huggie

3
Saya suka berpikir saya tidak dapat mengunggah tulisan ini karena akan menyebabkan bilangan bulat yang melimpah :)
Milo

hai @ram, Anda harus memilih jawaban untuk pertanyaan ini
Fattie

4
Saya tidak mengerti ... kode ini tidak akan membiarkan apa pun dipilih.
C. Tewalt

@matrixugly benar. Lebih tepat melakukan ini di dalam willSelectRowAt:. Lihat jawaban yang lebih lengkap di sini: stackoverflow.com/questions/12693402/…
HuaTham

117

Gunakan metode berikut dalam delegasi tampilan tabel didSelectRowAtIndexpath(Atau dari mana saja)

[myTable deselectRowAtIndexPath:[myTable indexPathForSelectedRow] animated:YES];

2
Perlu dicatat bahwa indexPathForSelectedRowini adalah metode dan bukan properti.
FreeAsInBeer

Manis! Tidak tahu [myTable indexPathForSelectedRow]. Saya mengulang-ulang sel sebelumnya. Terima kasih!
guptron

@FreeAsInBeer Apakah perbedaan ini penting entah bagaimana? Accessor properti adalah metode.
devios1

@chaiguy Tidak apa-apa jika Anda tidak keberatan rekan kerja menganggap Anda jahat .
FreeAsInBeer

1
@Supertecnoboff Tidak ada perbedaan kinerja antara kedua variasi.
FreeAsInBeer

38

Coba ini:

for (NSIndexPath *indexPath in tableView.indexPathsForSelectedRows) {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}


ini tidak didukung di iOS 11 Swift 4
Boris Nikolic

30

Mungkin bermanfaat untuk membuat ekstensi di Swift untuk ini.

Swift 4 dan Swift 5:

Ekstensi cepat (mis. Dalam file UITableViewExtension.swift):

import UIKit

extension UITableView {

    func deselectSelectedRow(animated: Bool)
    {
        if let indexPathForSelectedRow = self.indexPathForSelectedRow {
            self.deselectRow(at: indexPathForSelectedRow, animated: animated)
        }
    }

}

Gunakan misalnya:

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

    self.tableView.deselectSelectedRow(animated: true)
}

1
Menurut pendapat saya, jawaban ini lebih baik karena menempatkan kehancuran dalam viewWillAppear()metode membantu pengguna untuk memahami dari mana ia kembali.
MonsieurDart

yang sempurna seperti yang saya butuhkan
Patel Jigar

28

Silakan periksa dengan metode delegasi apakah itu benar atau tidak. Sebagai contoh;

-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

untuk

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

Memanggil metode yang salah sepanjang waktu ini, arghh !! Terima kasih!
Damir Kotoric

1
oh man .... pelengkapan otomatis berdarah !!! Butuh beberapa jam untuk mencari tahu !!! OMG ... Aku ingin menciummu!
George Asda


16

Ini adalah solusi untuk Swift 4

 in tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

tambahkan saja

tableView.deselectRow(at: indexPath, animated: true)

itu bekerja seperti pesona

contoh:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
//some code
}

sampai Anda menambahkan pilihan pada pengeditan dalam tampilan tabel Anda, tidak akan mungkin untuk memilih sel apa pun karena itu akan membatalkan pilihan ketika Anda selesai memilihnya :)
Mehdi Chennoufi

Ini tentu saja merupakan pendekatan yang benar, ketika Anda tidak sedang mengedit, ketika Anda "mengetuk baris untuk melakukan sesuatu"
Fattie

11

Selain mengatur sel seperti yang dipilih, Anda juga perlu memberi tahu tableView bahwa sel dipilih. Tambahkan panggilan ke metode -tableView:selectRowAtIndexPath:animated:scrollPosition:Anda willDisplayCell:: dan Anda akan dapat membatalkan pilihan seperti biasa.

- (void)tableView:(UITableView*)tableView 
  willDisplayCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        // SELECT CELL
        [cell setSelected:YES]; 
        // TELL TABLEVIEW THAT ROW IS SELECTED
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];   
    } 
}

Pastikan untuk menggunakan UITableViewScrollPositionNone untuk menghindari perilaku gulir yang aneh.


1
Tepat sekali. Saya berpikir bahwa [cell setSelected:YES]bisa dihilangkan: selectRowAtIndexPathakan mengurus sel selectednegara
spassas

Jawaban ini berfungsi untuk UITableView dengan beberapa pilihan. Jempolan.
Danny Bravo

6

Ini seharusnya bekerja:

[tableView deselectRowAtIndexPath:indexpath1 animated:NO];

Pastikan materialTable dan tableView menunjuk ke objek yang sama.

Apakah materi terhubung ke tableView di Interface Builder?


saya telah diuji dengan TIDAK tetapi itu juga tidak menyelesaikan masalah saya. tetapi saya memperbaiki masalah ini dengan cara lain sebagai reloaded Data ketika delegasi didselect dipecat.
Ram

6

Berdasarkan solusi saikiran, saya telah menulis ini, yang membantu saya. Pada file .m:

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

    if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
        selectedRowIndex = nil;

    }

    else {  self.selectedRowIndex = [indexPath retain];   }

    [tableView beginUpdates];
    [tableView endUpdates];

}

Dan pada file header:

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

Saya juga tidak terlalu berpengalaman, jadi periksa kebocoran memori dll.


6

Jika Anda ingin memilih sel tabel apa pun dengan klik pertama dan membatalkan pilihan dengan yang kedua, Anda harus menggunakan kode ini:

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

    if (self.selectedIndexPath && 
        [indexPath compare:self.selectedIndexPath] == NSOrderedSame) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
         self.selectedIndexPath = nil;
    } 
    else {
        self.selectedIndexPath = indexPath;
    }
}

5

Swift 4:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let cell = tableView.cellForRow(at: indexPath)
    if cell?.isSelected == true { // check if cell has been previously selected
        tableView.deselectRow(at: indexPath, animated: true)
        return nil
    } else {
        return indexPath
    }
}

2
Ini bekerja untuk saya di Swift 3. Baru saja menambahkan self.tableView(tableView, didDeselectRowAt: indexPath)setelah tableView.deselectRow...karena tidak dipanggil secara otomatis
elysch

4

Swift 2.0:

tableView.deselectRowAtIndexPath(indexPath, animated: true)

3

coba ini

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];

coba jelaskan jawaban Anda, kalau tidak itu seharusnya komentar.
Hugo Dozois

3
NSIndexPath * index = [self.menuTableView indexPathForSelectedRow];
[self.menuTableView deselectRowAtIndexPath:index animated:NO];

tempatkan kode ini sesuai dengan kode Anda dan Anda akan mendapatkan sel Anda terpilih.


3

Bisakah kamu mencoba ini?

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

    AppDelegate_iPad *appDelegte = 
    (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;

    UITableViewCell *prevSelectedCell = [tableView cellForRowAtIndexPath: indexpath1];
    if([prevSelectedCell isSelected]){
       [prevSelectedCell setSelected:NO];
    }
}

Ini berhasil untuk saya.


2

Swift 3.0:

Mengikuti bagian kepatuhan protokol dari panduan gaya swift ray wenderlich , untuk menjaga metode terkait dikelompokkan bersama, letakkan ekstensi ini di bawah kelas view controller Anda seperti itu:

// your view controller
class MyViewcontroller: UIViewController {
  // class stuff here
}

// MARK: - UITableViewDelegate
extension MyViewcontroller: UITableViewDelegate {
      // use the UITableViewDelegate method tableView(_:didSelectRowAt:)
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // your code when user select row at indexPath

        // at the end use deselectRow
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

1

Cepat

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    // your code

    // your code

    // and use deselect row to end line of this function

    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)

}

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

1

Cepat 3

Saya juga mengalami ini - ketika Anda menavigasi atau bersantai kembali ke tampilan tabel biasanya tidak membatalkan pilihan baris yang sebelumnya dipilih untuk Anda. Saya menempatkan kode ini di pengontrol tampilan tabel & berfungsi dengan baik:

override func viewDidAppear(_ animated: Bool) {
    if let lastSelectedRow = tableView.indexPathForSelectedRow {
        tableView.deselectRow(at: lastSelectedRow, animated: true)
    }
}

1

Cepat 3/4

Di ViewController:

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

Di Sel Kustom:

override func awakeFromNib() {
    super.awakeFromNib()
    selectionStyle = .none
}


0

Untuk membatalkan pilihan (DidDeselectRowAt) diaktifkan ketika diklik pertama kali karena data yang dimuat; Anda perlu memberi tahu tableView bahwa baris sudah dipilih untuk memulai, sehingga klik awal kemudian membatalkan pilihan baris:

// Swift 3:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if tableView[indexPath.row] == "data value"

        tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)

    }
}

0

Apa yang saya temukan adalah bahwa di atas pengaturan sel sebagai yang dipilih , Anda harus membiarkan tampilan tabel tahu untuk memilih baris di jalur indeks yang diberikan.

// Swift 3+  

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if appDelegate.indexPathDelegate.row == indexPath.row {
        self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
        cell.setSelected(true, animated: true)
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.