-didSelectRowAtIndexPath: tidak dipanggil

295

Saya sedang menulis aplikasi iOS dengan tampilan tabel di dalam tampilan tab. Di saya UITableViewController, saya menerapkan -tableView:didSelectRowAtIndexPath:, tetapi ketika saya memilih baris saat runtime, metode tidak dipanggil. Tampilan tabel sedang diisi, jadi saya tahu bahwa metode tableView lain di controller saya dipanggil.

Adakah yang tahu apa yang mungkin saya lakukan untuk mewujudkannya?

Matt Pfefferle
sumber
79
Anda juga mungkin memiliki gestureRecognizer di atas UITableView yang menyerap pilihan .. (salah satu kemungkinan)
M.Othman
Hati-hati jika tampilan tabel sedang diisi, itu berarti DataSource diatur dengan baik. Pemilihan merupakan bagian dari metode Delegasi. Jadi mungkin DataSource diatur dengan baik tetapi bukan Delegasi!
Thomas Besnehard
1
Hai M. Othman, komentar Anda persis apa yang salah dengan masalah saya sendiri. Apakah Anda tahu cara mengaktifkan gestureRecognizer UITableView?
yhl
15
Saya perhatikan bahwa jika saya mengetuk terus, ketuk itu akhirnya memanggil -didSelectRowAtIndexPath. Saya tahu topi karena saya memiliki pengenal gerakan ketukan di tampilan meja dan gerakan harus gagal terlebih dahulu sebelum menerima sentuhan. Meskipun aneh, animasi pemilihan tabel tidak terpengaruh oleh pengenal isyarat.
Hlung
6
Saya memiliki masalah yang sama di sini dan memiliki kesempatan yang beruntung untuk mengetahui bahwa Anda tidak dapat memiliki gestureRecognizer di atas UITableView. Terima kasih M. Othman!
vnchopra

Jawaban:

97

Kedengarannya mungkin kelas bukan UITableViewDelegateuntuk tampilan tabel itu, meskipun UITableViewControllerseharusnya diatur secara otomatis.

Adakah peluang Anda mereset delegasi ke kelas lain?

Hunter
sumber
7
Saya menemukan bahwa sementara pengontrol saya adalah UITableViewController, saya menggunakan widget UIViewController tua yang sederhana di UI Builder. Itu tidak berhasil. Ketika saya menghapus widget UIViewController dan menjatuhkan UITableViewController di tempatnya, semuanya berfungsi.
Matt Pfefferle
1
Kasus batas lain untuk semua orang - saya mengirim delegasi dalam kode dan lupa saya sebelumnya mengirim delegasi melalui storyboard .... yang terakhir untuk membuatnya menang.
Oliver Dungey
1
dapatkah Anda menunjukkan cara "mengatur ulang delegasi ke kelas lain"? Saya memiliki masalah yang sama dan tidak dapat menyelesaikannya
Alfro
1
myTableViewController.tableView.delegate = xxx
Hunter
534

Untuk berjaga-jaga seandainya seseorang melakukan kesalahan bodoh yang sama seperti yang saya lakukan:

Periksa apakah nama metode yang Anda harapkan didSelectmungkin secara tidak sengaja diperoleh didDeselectdengan cara tertentu. Butuh sekitar dua jam bagi saya untuk mencari tahu ...

Dschee
sumber
47
Masalah yang sama di sini. Itu karena XCode melengkapi secara otomatis Hapus pilihan sebelum Pilih.
user1021430
Demikian pula, saya telah menetapkan allowSelection = false, yang juga menghilangkan semua highlight seleksi, juga mencegah sel ditekan!
djinne95
503

Hal lain yang mungkin menyebabkan masalah adalah jenis pemilihan yang tidak dipilih:

Jenis pilihan UITableView

Harus Single Selectionuntuk seleksi normal, seharusnya tidak menjadi No Selection.

Untuk melakukan ini secara pemrograman, lakukan:

tableView.allowsSelection = YES
Dennis Krut
sumber
4
Saya terus menjalankan ini karena saya memiliki adegan yang selalu dalam mode edit dan saya selalu lupa untuk mengubah default dari "Tidak Ada Pilihan Selama Editing".
Simetris
3
Anda dapat menambahkan baris ini di -viewDidLoad Anda metode viewControlller NSParameterAssert (self.tableView.allowsSelection);
Nikolay Shubenkov
bagi mereka yang mengamati tableView.rx.itemSelected.subscribe tidak menelepon kembali, ini adalah masalah dan perbaikan di atas bekerja
Dhilip
sangat membantu ketika Anda mengambil alih beberapa basis kode dan memiliki kode menggunakan tombol dengan tag dan tidak memilih, dengan pilihan ini dinonaktifkan di storyboard 🙄
Nitin Alabur
Apakah tableView ini perilaku default?
Frostmourne
296

Kemungkinan lain adalah bahwa UITapGestureRecognizer dapat memakan acara tersebut, seperti yang terjadi di sini: https://stackoverflow.com/a/9248827/214070

Saya tidak curiga penyebab ini, karena sel-sel tabel masih akan menyorot biru seolah-olah keran berhasil.

bugloaf
sumber
Ini masalah saya! Terima kasih banyak!! Maksud saya jelas bekerja sebelumnya, tetapi berhenti bekerja setelah saya menerapkan UITapGestureRecognizer * tap = [[Alokasi UITapGestureRecognizer] initWithTarget: aksi diri: @selector (dismissKeyboard)]; [self.view addGestureRecognizer: ketuk];
coolcool1994
26
Saya memiliki masalah yang sama dengan Anda @ coolcool1994 baru saja menerapkan [ketuk setCancelsTouchesInView: NO]; dan memecahkan masalah tersebut.
nizx
Terima kasih, ini membantu saya. Dalam kasus saya didSelectRowAtIndexPathtidak hanya berfungsi setelah menghapus sel di commitEditingStyle. Lalu saya membuat UITapGestureRecognizerdan di tapAction:dapatkan indexPathdari sender.view( [self.tableView indexPathForCell:sender.view]) dan menelepon[self.tableView.delegate didSelectRowAtIndexPath:myIndexPath]
Alexmelyon
1
Ini adalah masalah saya juga .. tambahkan kode untuk menghapus tapgesture di tableview & itu berfungsi seperti pesona - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {UITapGestureRecognizer * gesture = [[UITapGestureRestureRestureRest ] init]; gesture.cancelsTouchesInView = TIDAK; [self.tableLihat addGestureRecognizer: gesture]; }
Udaya Sri
6
Terima kasih @nizx, dengan cepat 4 tap.cancelsTouchesInView = false
Ariven Nadar
150

Semua jawaban bagus, tapi ada satu lagi yang harus diperhatikan ...

(Khususnya saat membuat UITableView secara terprogram)

Pastikan tableView dapat merespons seleksi dengan mengatur [tableView setAllowsSelection:YES];atau menghapus baris apa pun yang mengaturnya NO.

Old McStopher
sumber
9
Saya akan menambahkan setAllowsSelectionDuringEditing:ke daftar (ketika tableview dalam mode editing)
alex-i
Terima kasih! Di IB saya harus mengubah nilai bagian "Pilihan" menjadi Single Selection.
Sasho
90

Jika masalah muncul dengan UITapGestureRecognizerAnda dapat memperbaiki ini:

  • di Storyboard:

masukkan deskripsi gambar di sini

dalam kode dengan Objective-C:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; 
[self.view addGestureRecognizer:tap];

[tap setCancelsTouchesInView:NO];

dalam kode dengan Swift:

let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)

tap.cancelsTouchesInView = false
Bartłomiej Semańczyk
sumber
67

Saya telah menemukan dua hal dalam situasi ini.

  1. Anda mungkin lupa mengimplementasikan protokol UITableViewDelegate, atau tidak ada outlet delegasi antara kelas Anda dan tampilan tabel Anda.

  2. Anda mungkin memiliki UIView di dalam baris Anda yang merupakan responden pertama dan menghilangkan klik Anda. Ucapkan UIButton atau yang serupa.

gilm
sumber
5
Itu mulai terjadi di iOS 7, menonaktifkan "Interaksi Pengguna Diaktifkan" dari pandangan dalam contentView diperbaiki ini.
Kof
1
@Kof memaku itu. Membuat UITableViewCell di pembangun antarmuka Xcode 5 membuatnya dengan interaksi pengguna diaktifkan = YA. Xcode 5 buruk!
jsd
44

Saya memiliki masalah yang sama. Dan itu sulit ditemukan. Tetapi di suatu tempat dalam kode saya adalah ini:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

Pasti return indexPath, kalau -tableView:didSelectRowAtIndexPath:tidak, tidak akan dipanggil.

JackPearse
sumber
2
untuk melakukan SelectRow At IndexPath tanda tangan yang benar adalah: - (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
coolcool1994
Bagi saya, itu tidak akan mulai memanggil tableView: didSelectRowAtIndexPath sampai saya menghapus willSelectRowAtIndexPath sepenuhnya
etayluz
38

Jika Anda menambahkan gestureRecognizer di atas UITableView, didSelectRowAtIndexPathtidak akan dipanggil.

Jadi, Anda perlu menggunakan metode delegasi gestureRecognizer untuk menghindari sentuhan dalam tampilan tertentu.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isDescendantOfView:YourTable]) {
        return NO;
    }
    return YES;
}
Vinu David Jose
sumber
3
if ([touch.view isDescendantOfView:YourTable])
Sudheesh
29

Saya mengalami masalah di mana setelah berbulan-bulan tidak melihat kode saya, saya lupa bahwa saya menerapkan metode berikut karena beberapa persyaratan yang tidak perlu

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath  *)indexPath{
    return NO;
}

Itu harus mengembalikan YA untuk satu baris untuk membuatnya dipilih.

cpt.neverm1nd
sumber
24

ANDA HARUS memilih opsi ini

masukkan deskripsi gambar di sini

tetapi jika Anda ingin membuat UITableViewtidak disorot pada mengklik maka Anda harus membuat perubahan pada UITableViewCellproperti.

Pilih opsi Tidak Ada untuk Seleksi seperti di bawah ini

masukkan deskripsi gambar di sini

Mohsin Qureshi
sumber
20

Saya telah meletakkan UITapGestureRecognizerpada tampilan meja saya untuk menghilangkan keyboard yang mencegah didSelectRowAtIndexPath:dipanggil. Semoga ini bisa membantu seseorang.

Groot
sumber
19

Saya memiliki masalah yang sama,

Alasannya menggunakan UITapGestureRecognizer. Saya ingin keyboard untuk menutup ketika saya mengetuk tempat lain. Saya menyadari bahwa ini mengesampingkan semua tindakan tap, itu sebabnya,didSelectRowAtIndexPath fungsi tidak dipanggil.

Ketika saya mengomentari baris terkait UITapGestureRecognizer, itu berfungsi. Selain itu Anda dapat memeriksa fungsi UITapGestureRecognizer selectorapakah mengetuk UITableViewCellatau tidak.

Jeyhun Karimov
sumber
14

Dalam kasus saya, didSelctRowAtIndexPath tidak menelepon adalah karena bahwa saya telah memilih tidak dalam Pemilihan milik tableView, set untuk seleksi tunggal memecahkan masalah saya

masukkan deskripsi gambar di sini

Naveed Ahmad
sumber
11

Untuk Xcode 6.4, Swift 1.2. "Tag" pilihan telah diubah dalam IB. Saya tidak tahu bagaimana dan mengapa. Mengaturnya ke "Pilihan Tunggal" membuat sel tampilan tabel saya dipilih kembali. masukkan deskripsi gambar di sini

MB_iOSDeveloper
sumber
10

Meskipun jawaban lain telah diterima, saya akan menambahkan satu lagi kemungkinan masalah dan solusi untuk orang yang mengamati masalah ini:

Jika Anda memiliki penghitungan referensi otomatis (ARC) dihidupkan, Anda mungkin menemukan bahwa bahkan setelah menetapkan controller Anda sebagai delegasi tampilan, pesan tampilan ke controller tidak diterima karena ARC menghapus controller. Rupanya pointer delegasi UITableView tidak dihitung sebagai referensi untuk ARC, jadi jika itu adalah satu-satunya referensi untuk itu, controller akan dealloc'd. Anda dapat memverifikasi apakah ini terjadi atau tidak dengan menerapkan metode dealloc pada controller dan mengatur breakpoint atau panggilan NSLog di sana.

Solusinya adalah melacak controller dengan referensi yang kuat di tempat lain, sampai Anda yakin Anda tidak akan membutuhkannya lagi.

Andrew Gorcester
sumber
Pengontrol dikumpulkan sampah saat pandangannya masih ditampilkan? Bisakah ini benar-benar terjadi?
Drux
@Drux Yap! Ketika ini terjadi pada saya, itu hampir versi pertama Obj-C dengan pengumpulan sampah yang digunakan di iOS dan jujur ​​mereka tidak melakukan pekerjaan dengan baik. Banyak referensi secara eksplisit atau implisit "lemah" yang, IMO, seharusnya kuat. Yang menyebabkan keanehan seperti pengumpulan sampah objek yang aktif digunakan oleh lapisan tampilan. Saya belum melakukan pekerjaan iOS dalam beberapa saat jadi saya tidak tahu apakah ini masih terjadi pada versi terbaru.
Andrew Gorcester
Kode saya memiliki masalah ukuran memori yang semakin besar dan saya memperbaikinya dan di tempat lain dalam kode setelah ini didSelect tidak akan dipanggil pertama kali saja. Saya tidak tahu apakah ini membenarkan masalah atau tidak.
Amber K
10

Ingatlah untuk mengatur sumber data dan mendelegasikan dalam metode viewDidLoad sebagai berikut:

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];
Carlos
sumber
Saya menelepon sumber data tetapi tidak mendelegasikan ... terima kasih!
Gmeister4
9

Masalah saya tidak ada di atas. Dan sangat timpang. Tapi saya pikir saya akan mendaftar di sini kalau-kalau itu membantu seseorang.

Saya memiliki tableViewControllercontroller "basis" saya dan kemudian saya membuat subkelas dari kontroler ini. Saya sedang menulis semua kode saya ditableView:didSelectRowAtIndexPath rutin di kelas "base". Benar-benar lupa bahwa secara default rutin ini juga telah dibuat (walaupun tanpa kode yang melakukan apa pun) di semua subkelas saya juga. Jadi ketika saya menjalankan aplikasi saya, ia menjalankan kode versi subkelas, tidak melakukan apa-apa, dan membuat saya sedih. Jadi tentu saja, setelah saya menghapus rutin dari subclass, itu menggunakan rutinitas kelas "dasar" dan saya dalam bisnis.

Aku tahu. Jangan tertawa. Tapi mungkin ini akan menyelamatkan seseorang saat aku kehilangan ...

Steve
sumber
8

Memberi 2 sen saya untuk ini.

Saya memiliki Custom UITableViewCell dan ada tombol yang menutupi seluruh sel, jadi ketika sentuhan terjadi, tombol itu dipilih dan bukan sel.

Baik menghapus tombol atau dalam kasus saya, saya mengatur Interaksi Pengguna Aktif ke salah pada tombol, dengan cara sel yang dipilih.

gmogames
sumber
8

Jika Anda membaca ini, jadi masih tidak menyelesaikan masalah.

Saya memiliki sel khusus , tempat kotak centang " Interaksi Pengguna Diaktifkan " dinonaktifkan. Jadi, saya aktifkan saja. Semoga berhasil.

HotJard
sumber
7

Saya baru saja mengalami ini dan seperti yang terjadi pada saya di masa lalu itu tidak berhasil karena saya tidak memperhatikan autocomplete ketika mencoba menambahkan metode dan saya benar-benar akhirnya menerapkan tableView:didDeselectRowAtIndexPath: alih-alih tableView:didSelectRowAtIndexPath:.

user486646
sumber
7

Pastikan Anda diimplementasikan tableView:didSelectRowAtIndexPathdan tidaktableView:didDeSelectRowAtIndexPath

Ini membuat saya lebih dari beberapa kali !!

SleepsOnNewspapers
sumber
5

Saya tahu sudah tua dan masalahnya telah teratasi, tetapi memiliki masalah yang serupa, saya pikir masalahnya ada pada UITableViewCell kustom saya, tetapi solusinya benar-benar berbeda - saya me-restart XCode :) dan kemudian berfungsi dengan baik! hampir seperti Windows :)

Lukasz
sumber
5

Jika tampilan tabel Anda dalam mode edit (mis. [tableView setEditing:YES animated:NO];), Anda perlu mengaturtableView.allowsSelectionDuringEditing = YES;

yvetterowe
sumber
4

Kesalahan lain yang bisa Anda lakukan (seperti yang saya lakukan): jika Anda menetapkan segue di sel, didSelectRowAtIndexPathtidak dipanggil. Anda harus mengatur segues Anda di pengontrol tampilan.

juanignaciosl
sumber
4

Tidak satu pun dari jawaban ini yang berhasil untuk saya. Setelah sekitar satu jam, saya menemukan sesuatu yang sangat berbahaya:

Saya memiliki tampilan tabel di dalam sel tampilan tabel lain. Saya memutuskan untuk membuat tampilan terlampir yang berisi tampilan tabel bagian dalam, antara lain. Saya memanggil viewView ini dan menghubungkannya di xib.

Ternyata UITableViewCell sudah memiliki contentView dan melakukan hal-hal aneh dengannya. Masalah ini teratasi dengan sendirinya ketika saya mengubah nama properti menjadi mainContentView dan menghubungkan kembali tampilan ke properti yang diganti nama ini.

xytor
sumber
4

Dalam kasus saya, saya secara dinamis menghitung ketinggian TableView's SuperViewpada saat beban. Karena kesalahan perhitungan, TableViewdiposisikan di luar SuperView. Itu TableViewditarik baik-baik saja, namun semua interaksi dinonaktifkan (dan didSelectRowAtIndexPathtidak pernah dipanggil). Sangat sulit dideteksi, karena tidak ada indikasi visual yang TableViewtidak dapat "diakses".

GK100
sumber
4

Dalam kasus saya masalahnya adalah saya memiliki UITableViewCellsubkelas dan saya telah menerapkan dua metode ini: touchesBegan:withEvent:& touchesEnded:withEventuntuk menangani animasi mewah saat disentuh. Tapi saya lupa menambahkan [super touchesBegan:touches withEvent:event];metode iklan[super touchesEnded:touches withEvent:event]; untuk juga memberi tahu sel induk tentang sentuhan.

Jadi mengubah kode ke berikut memecahkan masalah saya:

-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    [super touchesBegan:touches withEvent:event];
    //blah blah blah
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    //rest of the code
}
alternatiph
sumber
1
Dapat mengkonfirmasi bahwa ini menyebabkan masalah OP untuk saya khususnya
Josh Wolff
4

Dalam kasus saya, solusinya adalah mengubah TIDAK menjadi YA dalam fungsi di bawah ini.

iOS 9+

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
HonkyHonk
sumber
Ini juga masalah saya. Saya memiliki beberapa implementasi tableView dan lupa untuk memisahkan dua tableViews dalam metode ini.
turingtested