Wie hebe ich die Auswahl einer ausgewählten UITableView-Zelle auf?

212

Ich arbeite an einem Projekt, bei dem ich eine bestimmte Zelle vorwählen muss.

Ich kann eine Zelle mit auswählen -willDisplayCell, aber ich kann sie nicht abwählen, wenn der Benutzer auf eine andere Zelle klickt.

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

Kannst du helfen?

RAM
quelle
11
Diese Frage muss akzeptiert werden
Titouan de Bailleul

Antworten:

407

Verwenden Sie diesen Code

- (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.
quelle
1
Es gibt einen didDeselectRowAtIndexPath, mit dem die Auswahl des vorherigen deaktiviert werden kann.
Huggie
3
Ich denke gerne, dass ich diesen Beitrag nicht positiv bewerten kann, da er einen ganzzahligen Überlauf verursachen würde :)
Milo
Hallo @ram, müssen Sie eine Antwort auf diese Frage auswählen
Fattie
4
Ich verstehe nicht ... dieser Code lässt niemals zu, dass etwas ausgewählt wird.
C. Tewalt
@matrixugly ist richtig. Es ist besser, dies im Inneren zu tun willSelectRowAt:. Eine vollständigere Antwort finden Sie hier: stackoverflow.com/questions/12693402/…
HuaTham
117

Verwenden Sie die folgende Methode in den Delegaten der Tabellenansicht didSelectRowAtIndexpath(oder von überall).

[myTable deselectRowAtIndexPath:[myTable indexPathForSelectedRow] animated:YES];
Shamitha
quelle
2
Es ist erwähnenswert, dass dies indexPathForSelectedRoweine Methode und keine Eigenschaft ist.
FreeAsInBeer
Süss! Wusste nichts davon [myTable indexPathForSelectedRow]. Ich habe mich vorher durch die Zellen geschlungen. Vielen Dank!
Guptron
@FreeAsInBeer Ist diese Unterscheidung irgendwie wichtig? Eigenschaftszugriffsmethoden sind Methoden.
devios1
@chaiguy Das ist in Ordnung, wenn es Ihnen nichts ausmacht, wenn Ihre Kollegen Sie für böse halten .
FreeAsInBeer
1
@ Supertecnoboff Es gibt keinen Unterschied in der Leistung zwischen den beiden Varianten.
FreeAsInBeer
38

Versuche dies:

for (NSIndexPath *indexPath in tableView.indexPathsForSelectedRows) {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}
ikosdroid
quelle
1
Gute Arbeit ... Ich denke, 'Index' in der 2. Zeile sollte indexPath
El Tomato
Dies wird nicht unterstützt unter iOS 11 Swift 4
Boris Nikolic
30

Es kann nützlich sein, hierfür eine Erweiterung in Swift zu erstellen.

Swift 4 und Swift 5:

Schnelle Erweiterung (z. B. in einer UITableViewExtension.swift-Datei):

import UIKit

extension UITableView {

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

}

Verwenden Sie zB:

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

    self.tableView.deselectSelectedRow(animated: true)
}
Thomas Neuteboom
quelle
1
Meiner Meinung nach ist diese Antwort besser, da das Einfügen der Verwüstung in die viewWillAppear()Methode dem Benutzer hilft, zu verstehen, woher er zurückkommt.
MonsieurDart
das perfekte wie ich brauchte
Patel Jigar
28

Bitte überprüfen Sie mit der Delegate-Methode, ob sie korrekt ist oder nicht. Beispielsweise;

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

zum

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
jfalexvijay
quelle
Ich habe die ganze Zeit die falsche Methode aufgerufen, arghh !! Danke dir!
Damir Kotoric
1
oh man .... verdammte Autovervollständigung !!! Ich habe mehrere Stunden gebraucht, um es herauszufinden !!! OMG ... ich will dich küssen!
George Asda
22

Swift 4:

tableView.deselectRow(at: indexPath, animated: true)
Andrea.Ferrando
quelle
Muss nicht als nicht optional deklariert werden, aber das ist richtig.
Michael
16

Dies ist eine Lösung für Swift 4

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

einfach hinzufügen

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

es wirkt wie ein Zauber

Beispiel:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
//some code
}
tBug
quelle
Bis Sie beim Bearbeiten in Ihrer Tabellenansicht eine Auswahl hinzufügen, ist es unmöglich, eine Zelle auszuwählen, da diese nach Abschluss der Auswahl abgewählt wird :)
Mehdi Chennoufi
Dies ist sicherlich der richtige Ansatz, wenn Sie nicht bearbeiten, wenn Sie "auf eine Zeile tippen, um etwas zu tun"
Fattie
11

Zusätzlich zum Festlegen der Zelle als ausgewählt müssen Sie der tableView mitteilen, dass die Zelle ausgewählt ist. Fügen Sie -tableView:selectRowAtIndexPath:animated:scrollPosition:Ihrer willDisplayCell:Methode einen Aufruf hinzu : und Sie können die Auswahl wie gewohnt aufheben.

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

Stellen Sie sicher, dass Sie UITableViewScrollPositionNone verwenden, um ein ungewöhnliches Bildlaufverhalten zu vermeiden.

Drew C.
quelle
1
Absolut korrekt. Ich denke, das [cell setSelected:YES]könnte weggelassen werden: selectRowAtIndexPathkümmert sich um den selectedZustand der Zelle
Spassas
Diese Antwort funktioniert für UITableViews mit Mehrfachauswahl. Daumen hoch.
Danny Bravo
6

Das sollte funktionieren:

[tableView deselectRowAtIndexPath:indexpath1 animated:NO];

Stellen Sie einfach sicher, dass materialTable und tableView auf dasselbe Objekt zeigen.

Sind Materialien mit der tableView in Interface Builder verbunden?

Jordanien
quelle
Ich habe mit NEIN getestet, aber das löst mein Problem auch nicht. Aber ich habe dieses Problem auf eine andere Weise behoben, als Daten neu geladen wurden, wenn der Didselect-Delegierte jemals gefeuert hat.
Ram
6

Basierend auf der Saikirans-Lösung habe ich dies geschrieben, was mir geholfen hat. In der .m-Datei:

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

}

Und in der Header-Datei:

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

Ich bin auch nicht sehr erfahren, also überprüfe es noch einmal auf Speicherlecks usw.

Yunus Nedim Mehel
quelle
6

Wenn Sie mit dem ersten Klick eine Tabellenzelle auswählen und mit dem zweiten abwählen möchten, sollten Sie diesen Code verwenden:

- (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-Liebe-NY
quelle
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
quelle
2
Dieser arbeitete für mich in Swift 3. Gerade hatte hinzuzufügen self.tableView(tableView, didDeselectRowAt: indexPath)nach , tableView.deselectRow...weil sie nicht automatisch aufgerufen wurde
elysch
4

Swift 2.0:

tableView.deselectRowAtIndexPath(indexPath, animated: true)
Anit Kumar
quelle
3

Versuche dies

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
EnasAZ
quelle
Versuchen Sie, Ihre Antwort zu erklären, sonst sollte es ein Kommentar sein.
Hugo Dozois
3
NSIndexPath * index = [self.menuTableView indexPathForSelectedRow];
[self.menuTableView deselectRowAtIndexPath:index animated:NO];

Platzieren Sie diesen Code entsprechend Ihrem Code und Sie werden Ihre Zelle abgewählt.

rahulchona
quelle
3

Kannst du das versuchen?

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

Es hat bei mir funktioniert.

Dattatraya Anarase
quelle
2

Swift 3.0:

Um die entsprechenden Methoden in Gruppen zu halten, folgen Sie dem Abschnitt zur Protokollkonformität des Ray Wenderlich Swift Style Guide , und fügen Sie diese Erweiterung wie folgt unter Ihre View Controller-Klasse ein:

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

Schnell

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

Swift 3

Ich bin auch darauf gestoßen - wenn Sie zur Tabellenansicht navigieren oder zurückspulen, wird die zuvor ausgewählte Zeile normalerweise nicht für Sie abgewählt. Ich habe diesen Code in den Table View Controller eingefügt und er funktioniert gut:

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

Swift 3/4

In ViewController:

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

In der benutzerdefinierten Zelle:

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

schnell 3.0

    tableView.deselectRow(at: indexPath, animated: true)
Marcelo Gracietti
quelle
0

Deaktivieren der Auswahl (DidDeselectRowAt) beim ersten Klicken aufgrund vorinstallierter Daten; Sie müssen die tableView darüber informieren, dass die Zeile bereits ausgewählt ist, damit durch einen ersten Klick die Auswahl der Zeile aufgehoben wird:

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

Ich habe festgestellt, dass Sie zusätzlich zum Festlegen der ausgewählten Zelle die Tabellenansicht informieren müssen, um die Zeile am angegebenen Indexpfad auszuwählen .

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