UITableViewCell neden vurgulanmış olarak kalıyor?


146

Bir tablo görünümü hücresine dokunulduktan sonra vurgulanmış kalmasına ne sebep olur? Hücreyi tıklıyorum ve ayrıntı görünümü itilirken vurgulanmış olarak kaldığını görebiliyorum. Ayrıntılı görünüm açıldıktan sonra hücre hala vurgulanır.

Yanıtlar:


263

Gözlerinde farklı didSelectRowAtIndexPatharamak gerekir deselectRowAtIndexPathhücreyi seçimini kaldırmak için.

Yani içinde başka ne yapıyorsanız didSelectRowAtIndexPathonu da çağırın deselectRowAtIndexPath.

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

11
deselectRowAtIndexPathSatırı seçmek yeni bir görünüm getirirse, görünümümdeDidAppear'ı çağırmayı tercih ederim .
notnoop

5
Aslında orası onu aramak için doğru yer değil, gerçekten ... tablolarla bir Apple uygulamasını kullanmayı deneyin (Kişiler iyi bir tanesidir) ve yeni bir ekrana geçtikten sonra, geri döndüğünüzde hücrenin hala vurgulanmış olduğunu göreceksiniz. seçimi kaldırılmadan önce kısaca. Teoride, seçimini kendi başına kaldırması için fazladan bir iş yapmanıza gerek olmadığını düşünüyorum, bu nedenle görünümde kodlamaDidAppear gerekli olmamalı ...
Kendall Helmstetter Gelner

6
@Kendall, @ 4thSpace: Belki de son yorumum kime atıfta bulunduğum konusunda kafa karıştırıcıydı, bunun için özür dilerim. UITableViewController -deselectRowAtIndexPath:animated:yöntemi tableView özelliğinden çağırır -viewDidAppear. Ancak, bir UIViewController alt sınıfında bir tablo görünümünüz varsa -deselectRowAtIndexPath:animated:, -viewDidAppearkendiniz çağırmalısınız . :)
Daniel Tull

5
Benim UITableViewController alt sınıfımda, aslında -viewWillAppear:onu bozan bir geçersiz kılma oldu . [super viewWillAppear:animated]Tekrar çalışması için bir çağrı ekleniyor.
Ben Challenor

5
3.2 beri otomatik seçiminin iptali davranış oluşur UITableViewControllerbireyin clearsSelectionOnViewWillAppearmülkiyet olarak ayarlanır YES(varsayılan) ve engelledi değil [super viewWillAppear]denilmekten.
defragged

62

Bunu yapmanın en temiz yolu 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];
    }
}

Bu şekilde, olması gerektiği gibi, denetleyiciye geri döndüğünüzde seçimi soldurma animasyonuna sahip olursunuz.

Http://forums.macrumors.com/showthread.php?t=577677 adresinden alınmıştır

Swift versiyonu

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)
    }
}

1
Bu, çoğu insanın UITableViewController kullanmazlarsa isteyeceğini umduğum şeydir. +1
MikeB

3
İnsanların şu anda ne yaptığını merak ediyorum, çünkü iOS 7 kullanıcının 'geri çekilmesine' izin veriyor. Kısmen sürüklemek ancak daha sonra eylemi tamamlamamak, viewWillAppear'ı çalıştırır. Kullanıcı gerçek için geri döndüğünde, satır seçilmeyecektir.
Ben Packard

1
@BenPackard viewDidAppearbunun yerine onu arayın .
squarefrog

@Jessica indexPathForSelectedRowÇağrı nil dönebilir, bu yüzden kontrol edilmelidir. Dokümantasyon şunları belirtir : Seçilen satırın satır ve bölüm dizinlerini tanımlayan bir dizin yolu veya dizin yolu geçersizse sıfır.
Gordonium

bu, kabul edilen cevap olarak belirtilmelidir, daha kullanıcı arayüzü dostudur, böylece kullanıcı geri döndükten sonra seçime ulaşabilir, mükemmel 👌
Yahya Alshaar

20

Alt sınıf mı yaptınız -(void)viewWillAppear:(BOOL)animated? [super viewWillAppear:animated];Özel yönteminizde arama yapmadığınızda seçilen UITableViewCell seçimi kaldırılmaz .


19

Swift kullanıcıları için bunu kodunuza ekleyin:

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

Paulthenerd'in cevabı, Obj-C yerine Swift dışında.


1
kendi kendine seçilmiyor mu, yani gitmesine izin verdiğin an?
Honey

@Honey Muhtemelen iOS'un önceki bir sürümünde veya görünümün kaybolması üzerine, ancak kesinlikle şimdi iOS 10'da (muhtemelen daha önce) ve üzeri değil.
Jamie Birch

9

Swift 3 Çözümü

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

7

Bir UITableViewCell kullanıyorsanız, aşağıdaki satırı yorumlayın

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

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

}

Bu yardımcı olur umarım.


4

Swift 4 ile güncellendi

Birkaç deneyden sonra, yine önceki cevaplara dayanarak, en iyi davranışın 2 şekilde elde edilebileceği sonucuna vardım: (pratikte neredeyse aynı)

// 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)
    }
}

Kişisel olarak ilk çözümü benimsiyorum çünkü bu daha kısa ve öz. TableView'unuza döndüğünüzde küçük bir animasyona ihtiyacınız varsa başka bir olasılık da kullanmaktır 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)
    }
}

Son olarak, bir UITableViewController kullanıyorsanız, clearsSelectionOnViewWillAppear özelliğinden de yararlanabilirsiniz .


3

Kendall Helmstetter Gelner'ın yorumunda tanımladığı davranışı elde etmek için, büyük olasılıkla deselectRowAtIndexPath istemezsiniz, bunun yerine denetleyicinizdeki clearsSelectionOnViewWillAppear özelliğini istersiniz. Belki de bu yanlışlıkla EVET olarak ayarlanmıştır?

Yeni UITableViewController alt sınıfları için varsayılan Apple şablonundaki yoruma bakın:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

2

Bu sorunu detaya inme uygulamam için de alıyordum. VC olarak adlandıracağım bir viewcontroller, başka bir ViewController'a bastıktan sonra geri döndükten sonra, VC'de seçilen hücre vurgulanmış olarak kaldı. Uygulamamda, detaylandırmamın ikinci düzeyini (üç düzeyden) işlemek için VC oluşturdum.

Benim durumumdaki sorun, VC'nin bir UIViewController (TableView içeren bir View içeren) olmasıdır. Bunun yerine VC'yi bir UITableViewController (TableView içeren) yaptım. UITableViewController sınıfı, bir itmeden döndükten sonra tablo hücresinin vurgulamasını otomatik olarak kaldırır. " TableView'da deselectRowAtIndexPath ile ilgili sorun" yazısının ikinci yanıtı , bu soruna daha eksiksiz bir yanıt verir.

Kök görüntüleme denetleyicisi için sorun oluşmadı çünkü uygulamayı XCode'da "Gezinme Tabanlı Uygulama" olarak oluşturduğumda, ortaya çıkan kök görünüm denetleyicisi zaten UITableViewController alt sınıfına yapılmıştı.


1

Bunların hiçbiri sizin için işe yaramazsa, şu geçici çözümü düşünün:

Çağrı yapmak için gevşeme segmenti kullanın:

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

Bunu neden yapıyorsun? Öncelikle, seçimi kaldırma kodunun doğru zamanda çalışmasını sağlamakta sorun yaşıyorsanız. ViewWillAppear üzerinde çalışmama konusunda sorun yaşadım, bu yüzden gevşeme çok daha iyi çalıştı.

Adımlar:

  1. Çözme segmentini (veya yukarıdan yapıştırın) 1. VC'nize (tablonun olduğu) yazın

  2. 2. VC'ye gidin. Bu VC'yi kapatmak için kullandığınız İptal / Bitti / Etc düğmesinden Control tuşunu basılı tutarak sürükleyin ve üstteki Çıkış Simgesine sürükleyin.

  3. 1. adımda oluşturduğunuz çözme segmentini seçin

    İyi şanslar.


Bu, viewDidAppear'ın çalışmadığı zamanlar için en iyi çözümdür (yani, alt görünüm mod olarak bir form sayfası olarak sunuluyorsa ve tüm ekranı kapsamıyorsa).
pheedsta

1

CoreData kullanıyorum, bu nedenle benim için çalışan kod, Swift'de çeşitli yanıtlardan fikirlerin bir kombinasyonuydu:

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

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

1

Swift 5 Çözümü:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}

0

Uzun zamandır aynı sorunu yaşıyorum, bu yüzden başka birinin mücadele etmesi durumunda:

Kendinize bir göz atın -tableView: cellForRowAtIndexPath:ve hücreler oluşturup oluşturmadığınızı veya bir 'yeniden kullanım tanımlayıcısı' kullanıp kullanmadığınızı görün. İkincisi ise, IB'deki tablonuzun bu tanımlayıcıya sahip bir hücreye sahip olduğundan emin olun. Tanımlayıcıyı yeniden kullanmıyorsanız, her satır için yeni bir hücre oluşturun.

Bu, daha sonra tablonuza göründüğünde beklenen 'soluk seçili satırı' vermelidir.


0

Bu yöntemi UITableViewCell sınıfında kullanın

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

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

0

Swift 3 için: viewDidDisappear'da kullanmayı tercih ederim

Tanımlamak:-

    var selectedIndexPath = IndexPath()

ViewDidDisappear: -

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

DidSelectRowAtIndexPath içinde: -

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

0

hücre dokunduktan sonra vurgulanmış olarak kalırsa, UITabelView yöntemini çağırabilirsiniz,

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

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

}

Veya aşağıdaki yöntemi kullanabilir ve gereksinimlerinize göre değiştirebilirsiniz,

// 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

Xcode 10, Swift 4

Aynı sorunu yaşadım ve tableViewController'ımın altındaki viewWillAppear için boş bir çağrı bıraktığımı keşfettim. Boş geçersiz kılma işlevini kaldırdıktan sonra, tablo artık tableView görünümüne dönüldüğünde satır vurgulu olarak kalmadı.

sorun fonk

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

boş işlevi kaldırmak sorunumu çözdü.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.