Seçili bir UITableView hücresinin seçimi nasıl kaldırılır?


212

Belirli bir hücreyi önceden seçmem gereken bir proje üzerinde çalışıyorum.

Kullanarak bir hücreyi önceden seçebilirim -willDisplayCell, ancak kullanıcı başka bir hücreyi tıkladığında seçimi kaldıramıyorum.

- (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];
}

Yardım edebilir misin?


11
Bu sorunun kabul edilmiş bir cevabı olmalı
Titouan de Bailleul

Yanıtlar:


408

bu kodu kullan

- (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
Bir öncekinin seçimini kaldırmak için kullanılacak bir didDeselectRowAtIndexPath var.
huggie

3
Tamsayı taşmasına neden olacağı için bu gönderiyi oylayamayacağımı düşünüyorum :)
Milo

merhaba @ram, bu soruya bir cevap seçmelisin
Fattie

4
Anlamıyorum ... bu kod hiçbir şey seçilmesine izin asla.
C. Tewalt

@matrixugly doğru. Bunu içeride yapmak daha uygun willSelectRowAt:. Burada daha eksiksiz bir cevap görün: stackoverflow.com/questions/12693402/…
HuaTham

117

Tablo görünümü temsilcisinin aşağıdaki yöntemini kullanın didSelectRowAtIndexpath(Veya herhangi bir yerden)

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

2
indexPathForSelectedRowBir özellik değil, bir yöntem olduğunu belirtmek gerekir .
FreeAsInBeer

Tatlı! Bilmiyordum [myTable indexPathForSelectedRow]. Daha önce hücreler arasında dolaşıyordum. Teşekkürler!
guptron

@FreeAsInBeer Bu ayrım bir şekilde önemli mi? Mülkiyet erişimcileri yöntemlerdir.
devios1

@chaiguy İş arkadaşlarınızın sizi kötülük olarak düşünmesine aldırmazsanız sorun değil .
FreeAsInBeer

1
@Supertecnoboff İki varyasyon arasında performans farkı yoktur.
FreeAsInBeer

38

Bunu dene:

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

1
Aferin ... Sanırım 2. satırdaki 'index' indeks olmalı Path
El Tomato

bu iOS 11 Swift 4'te desteklenmiyor
Boris Nikolic

30

Bunun için Swift'te bir uzantı oluşturmak yararlı olabilir.

Swift 4 ve Swift 5:

Swift uzantısı (örn. UITableViewExtension.swift dosyasında):

import UIKit

extension UITableView {

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

}

Örneğin:

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

    self.tableView.deselectSelectedRow(animated: true)
}

1
Benim düşünceme göre, bu cevap daha iyidir çünkü ıssızlığı viewWillAppear()yönteme koymak kullanıcının nereden geldiğini anlamasına yardımcı olur.
MonsieurDart

gerektiği gibi mükemmel biri
Patel Jigar

28

Lütfen temsilci yöntemiyle doğru olup olmadığını kontrol edin. Örneğin;

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

için

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

Bütün zaman boyunca yanlış metodu çağırıyordum, arghh !! Teşekkür ederim!
Damir Kotoric

1
oh adamım ... kanlı otomatik tamamlama !!! Anlamak için birkaç saat sürdü !!! Aman Tanrım ... Seni öpmek istiyorum!
George Asda

22

Hızlı 4:

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

İsteğe bağlı olmayan ilan edilmesi gerekmez, ancak bu doğrudur.
Michael

16

Bu Swift 4 için bir çözüm

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

sadece ekle

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

mucizevi şekilde çalışır

misal:

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

tablo görünümünüzde düzenleme seçimini ekleyene kadar, herhangi bir hücreyi seçmek imkansız olacaktır çünkü seçtiğinizde seçimini kaldıracaktır :)
Mehdi Chennoufi

Düzenlemediğinizde, "bir şey yapmak için bir sıraya dokunduğunuzda" bu kesinlikle doğru yaklaşımdır
Fattie

11

Hücreyi seçili olarak ayarlamaya ek olarak, tableView öğesine hücrenin seçili olduğunu bildirmeniz gerekir. Bir çağrı ekleyin -tableView:selectRowAtIndexPath:animated:scrollPosition:sizin için willDisplayCell:yöntemiyle: ve normal olarak seçimini kaldırmak mümkün olacak.

- (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];   
    } 
}

Tek kaydırma davranışını önlemek için UITableViewScrollPositionNone'u kullandığınızdan emin olun.


1
Kesinlikle doğru. Bence bu [cell setSelected:YES]ihmal edilebilir: selectRowAtIndexPathhücrenin selecteddurumu ile
ilgilenecek

Bu cevap, birden fazla seçime sahip UITableView için geçerlidir. Başparmak havaya.
Danny Bravo

6

Bu çalışmalı:

[tableView deselectRowAtIndexPath:indexpath1 animated:NO];

MaterialTable ve tableView öğelerinin aynı nesneyi gösterdiğinden emin olun.

Malzemeler Interface Builder'da tableView'a bağlı mı?


HAYIR ile test ettim ama bu da sorunumu çözmedi. ama didselect delege ateş her zaman yeniden yüklenen Veri olarak başka bir yol ile bu sorunu düzeltildi.
Ram

6

Saikirans çözümüne dayanarak bunu yazdım, bu bana yardımcı oldu. .M dosyasında:

- (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];

}

Ve başlık dosyasında:

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

Ben de çok deneyimli değilim, bu yüzden bellek sızıntıları vb. İçin iki kez kontrol edin.


6

İlk tıklamayla herhangi bir tablo hücresini seçmek ve ikinci tıklamayla seçimi kaldırmak istiyorsanız, bu kodu kullanmalısınız:

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

Hızlı 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
Swift 3. Just benim için çalıştı Bu eklemek zorunda self.tableView(tableView, didDeselectRowAt: indexPath)sonra tableView.deselectRow...otomatik çağrılmadı çünkü
elysch

4

Swift 2.0:

tableView.deselectRowAtIndexPath(indexPath, animated: true)

3

bunu dene

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

Cevabınızı açıklamaya çalışın, aksi takdirde bir yorum olmalıdır.
Hugo Dozois

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

Bu kodu kodunuza göre yerleştirin ve hücrenizin seçimini kaldırın.


3

Bunu deneyebilir misin?

- (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];
    }
}

Benim için çalıştı.


2

Swift 3.0:

Aşağıdaki hızlı stil kılavuzu wenderlich ray protokol uygunluk bölümünde , birlikte gruplandırılmış ilgili yöntemleri tutmak için, böyle görüşünüz denetleyici sınıfının altındaki bu uzantıyı koydu:

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

hızlı

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

Hızlı 3

Ben de bununla karşılaştım - tablo görünümüne geri döndüğünüzde veya gevşediğinizde genellikle sizin için önceden seçilen satırın seçimini kaldırmaz. Bu kodu tablo görünümü denetleyicisine koydu ve iyi çalışıyor:

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

1

Hızlı 3/4

ViewController'da:

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

Özel Hücrede:

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


0

Önceden yüklenmiş veriler nedeniyle ilk kez tıklandığında (DidDeselectRowAt) tetiklemesini kaldırmak için; Tablo Görünümünü başlatmak için satırın zaten seçili olduğunu bildirmeniz gerekir, böylece ilk tıklama daha sonra satırın seçimini kaldırır:

// Hızlı 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

Bulduğum şey, hücreyi seçili olarak ayarlamanın üstünde , tablo görünümünün verilen dizin yolundaki satırı seçmesini bilmeniz gerektiğidir .

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