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?

Ram
sumber
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)
}
Saikiran K
sumber
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];
Shamitha
sumber
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];
}
ikosdroid
sumber
1
El Tomato
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)
}
Thomas Neuteboom
sumber
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
jfalexvijay
sumber
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
22

Swift 4:

tableView.deselectRow(at: indexPath, animated: true)
Andrea.Ferrando
sumber
Tidak perlu dinyatakan non-opsional tetapi ini benar.
Michael
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
}
tBug
sumber
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.

Drew C
sumber
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?

Yordania
sumber
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.

Yunus Nedim Mehel
sumber
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;
    }
}
CHiP-love-NY
sumber
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
    }
}
Serguei Vinnitskii
sumber
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)
Anit Kumar
sumber
3

coba ini

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
EnasAZ
sumber
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.

rahulchona
sumber
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.

Dattatraya Anarase
sumber
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)
    }
}
ronatory
sumber
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)

}
Programer_saeed
sumber
1
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}
Aayushi
sumber
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)
    }
}
Trev14
sumber
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
}
Sevy11
sumber
0

cepat 3.0

    tableView.deselectRow(at: indexPath, animated: true)
Marcelo Gracietti
sumber
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)

    }
}
Arkelyan
sumber
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)
    }
}
David Para
sumber