Jawaban:
Di Anda, didSelectRowAtIndexPath
Anda perlu menelepon deselectRowAtIndexPath
untuk membatalkan pilihan sel.
Jadi, apa pun yang Anda lakukan di dalam diri didSelectRowAtIndexPath
Anda, panggil saja deselectRowAtIndexPath
juga.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Do some stuff when the row is selected
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-deselectRowAtIndexPath:animated:
metode dari properti tableView-nya -viewDidAppear
. Namun, jika Anda memiliki tampilan tabel dalam subclass UIViewController, Anda harus menghubungi -deselectRowAtIndexPath:animated:
dari -viewDidAppear
diri sendiri. :)
-viewWillAppear:
. Menambahkan panggilan untuk [super viewWillAppear:animated]
membuatnya berfungsi kembali.
UITableViewController
's clearsSelectionOnViewWillAppear
properti diatur ke YES
(yang merupakan default), dan Anda tidak dicegah [super viewWillAppear]
dari yang disebut.
Cara paling bersih untuk melakukannya adalah pada 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];
}
}
Dengan cara ini Anda memiliki animasi memudar pemilihan ketika Anda kembali ke controller, sebagaimana mestinya.
Diambil dari http://forums.macrumors.com/showthread.php?t=577677
Versi cepat
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)
}
}
viewDidAppear
saja.
indexPathForSelectedRow
Panggilan dapat mengembalikan nol sehingga harus diperiksa. Dokumentasi menyatakan : Jalur indeks yang mengidentifikasi baris dan indeks bagian dari baris yang dipilih, atau nihil jika jalur indeks tidak valid.
Apakah Anda subkelas -(void)viewWillAppear:(BOOL)animated
? UITableViewCell yang dipilih tidak akan membatalkan pilihan ketika Anda tidak memanggil [super viewWillAppear:animated];
metode kustom Anda.
Untuk pengguna Swift, tambahkan ini ke kode Anda:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Ini jawaban paulthenerd kecuali di Swift bukan Obj-C.
Diperbarui dengan Swift 4
Setelah beberapa percobaan, juga berdasarkan jawaban sebelumnya, saya mendapat kesimpulan bahwa perilaku terbaik dapat dicapai dalam 2 cara: (hampir identik dalam praktik)
// 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)
}
}
Saya pribadi mengadopsi solusi pertama, karena itu lebih ringkas. Kemungkinan lain, jika Anda memerlukan sedikit animasi saat kembali ke tableView, adalah menggunakan 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)
}
}
Terakhir tetapi tidak kalah pentingnya, jika Anda menggunakan UITableViewController, Anda juga dapat memanfaatkan properti ini untuk menghapusSelectionOnViewWillAppear .
Untuk mendapatkan perilaku yang dijelaskan oleh Kendall Helmstetter Gelner dalam komentarnya, Anda mungkin tidak ingin membatalkan pilihanRowAtIndexPath melainkan properti clearsSelectionOnViewWillAppear pada pengontrol Anda. Mungkin ini diatur ke YA karena kecelakaan?
Lihat komentar di template Apple default untuk subclass UITableViewController baru:
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
}
Saya mendapatkan masalah ini juga untuk aplikasi drill-down saya. Setelah viewcontroller, yang saya sebut VC, kembali setelah mendorong ViewController lain, sel yang dipilih dalam VC tetap disorot. Dalam aplikasi saya, saya telah membuat VC untuk menangani level kedua (dari tiga level) dari drill-down saya.
Masalah dalam kasus saya adalah bahwa VC adalah UIViewController (yang berisi tampilan yang berisi TableView). Saya malah membuat VC sebagai UITableViewController (yang berisi TableView). Kelas UITableViewController secara otomatis menangani penonaktifanan sel tabel setelah kembali dari push. Jawaban kedua untuk posting " Masalah dengan deselectRowAtIndexPath di tableView " memberikan jawaban yang lebih lengkap untuk masalah ini.
Masalahnya tidak terjadi untuk root viewcontroller karena ketika saya membuat aplikasi sebagai "Aplikasi berbasis Navigasi" di XCode, viewcontroller root yang dihasilkan sudah dibuat untuk subkelas UITableViewController.
Jika tidak ada yang cocok untuk Anda, pertimbangkan ini:
Gunakan segue bersantai untuk menelepon:
@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
if let index = tableView.indexPathForSelectedRow {
tableView.deselectRowAtIndexPath(index, animated: true)
}
}
Kenapa melakukan ini? Terutama jika Anda mengalami masalah dalam menjalankan kode yang tidak dipilih untuk dijalankan pada waktu yang tepat. Saya mengalami masalah dengan itu tidak bekerja pada viewWillAppear sehingga bersantai bekerja jauh lebih baik.
Langkah:
Tuliskan segue rileks (atau tempel dari atas) ke VC 1 Anda (yang berisi tabel)
Pergi ke VC ke-2. Seret kontrol dari tombol Batal / Selesai / Dll yang Anda gunakan untuk mengabaikan VC itu dan seret ke Ikon Keluar di bagian atas.
Pilih segmen bersantai yang Anda buat di langkah 1
Semoga berhasil.
Saya menggunakan CoreData sehingga kode yang bekerja untuk saya adalah kombinasi ide dari berbagai jawaban, di Swift:
override func viewDidAppear(_ animated: Bool) {
if let testSelected = yourTable.indexPathForSelectedRow {
yourTable.deselectRow(at: testSelected, animated: true)
}
super.viewDidAppear(true)
}
Saya sudah memiliki masalah yang sama sejak lama sehingga kalau-kalau ada orang lain yang berjuang:
Lihatlah Anda -tableView: cellForRowAtIndexPath:
dan lihat apakah Anda membuat sel atau menggunakan 'reuse identifier'. Jika yang terakhir, pastikan bahwa tabel Anda di IB memiliki sel dengan pengenal itu. Jika Anda tidak menggunakan Pengidentifikasi Penggunaan Kembali cukup buat sel baru untuk setiap baris.
Ini kemudian akan memberi meja Anda 'garis memudar yang diharapkan' diharapkan muncul.
Untuk Swift 3: Saya lebih suka menggunakannya di viewDidDisappear
Menetapkan:-
var selectedIndexPath = IndexPath()
Di viewDidDisappear: -
override func viewDidDisappear(_ animated: Bool) {
yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}
Di didSelectRowAtIndexPath: -
func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
selectedIndexPath = indexPath
}
jika sel tetap disorot setelah menyentuhnya, Anda dapat memanggil metode UITabelView,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
`[tableView deselectRowAtIndexPath:indexPath animated:YES];`
}
Atau, Anda dapat menggunakan metode berikut dan memodifikasinya sesuai dengan kebutuhan Anda,
// 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()
}
}
Xcode 10, Swift 4
Saya memiliki masalah yang sama dan menemukan saya meninggalkan panggilan kosong ke viewWillAppear di bagian bawah tableViewController saya. Setelah saya menghapus fungsi override kosong baris tidak lagi disorot setelah kembali ke tampilan tableView.
masalah func
override func viewWillAppear(_ animated: Bool) {
// need to remove this function if not being used.
}
menghapus fungsi kosong memecahkan masalah saya.
deselectRowAtIndexPath
di viewDidAppear saya, jika pilih baris menampilkan tampilan baru.