webentwicklung-frage-antwort-db.com.de

Warum bleibt UITableViewCell hervorgehoben?

Was würde bewirken, dass eine Tabellensichtzelle nach dem Berühren hervorgehoben bleibt? Ich klicke auf die Zelle und kann sehen, dass sie hervorgehoben wird, wenn eine Detailansicht verschoben wird. Nachdem die Detailansicht geöffnet wurde, wird die Zelle immer noch hervorgehoben.

134
4thSpace

In Ihrer didSelectRowAtIndexPath müssen Sie deselectRowAtIndexPath aufrufen, um die Auswahl der Zelle aufzuheben.

Was auch immer Sie sonst in didSelectRowAtIndexPath tun, Sie haben es auch als deselectRowAtIndexPath bezeichnet.

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

Der sauberste Weg, dies zu tun, ist auf 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];
    }
}

Auf diese Weise haben Sie die Animation zum Ausblenden der Auswahl, wenn Sie zum Controller zurückkehren, wie es sein sollte.

Entnommen aus http://forums.macrumors.com/showthread.php?t=577677

Swift-Version

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

Hast du die Unterklasse -(void)viewWillAppear:(BOOL)animated? Die ausgewählte UITableViewCell wird nicht abgewählt, wenn Sie in Ihrer benutzerdefinierten Methode nicht [super viewWillAppear:animated]; aufrufen.

20
HansPinckaers

Für die Swift-Benutzer fügen Sie dies Ihrem Code hinzu: 

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

Es ist Paulthenerds Antwort, außer in Swift anstelle von Obj-C. 

17

Swift 3 Lösung

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

Wenn Sie eine UITableViewCell verwenden, kommentieren Sie die folgende Zeile 

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

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

}

Hoffe das hilft.

7
Shantanu Phate

Mit Swift 4 aktualisiert

Nach wenigen Experimenten, die ebenfalls auf früheren Antworten basierten, habe ich die Schlussfolgerung gezogen, dass das beste Verhalten auf zwei Arten erreicht werden kann:

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

Ich persönlich übernehme die erste Lösung, weil sie einfach prägnanter ist. Eine andere Möglichkeit, wenn Sie eine kleine Animation benötigen, wenn Sie zu Ihrem tableView zurückkehren, ist 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)
    }
}

Wenn Sie einen UITableViewController verwenden, können Sie auch die Eigenschaft clearsSelectionOnViewWillAppear nutzen. 

Um das Verhalten zu erhalten, das Kendall Helmstetter Gelner in seinem Kommentar beschreibt, möchten Sie wahrscheinlich nicht deselectRowAtIndexPath, sondern die clearsSelectionOnViewWillAppear-Eigenschaft Ihres Controllers. Vielleicht wurde dies aus Versehen auf JA gesetzt? 

Siehe den Kommentar in der Standardvorlage von Apple für neue UITableViewController-Unterklassen:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

Ich bekam dieses Problem auch für meine Drilldown-Anwendung. Nachdem ein Viewcontroller, den ich VC nenne, nach dem Drücken eines anderen ViewControllers zurückkehrt, bleibt die ausgewählte Zelle in VC hervorgehoben. In meiner App hatte ich VC erstellt, um die zweite Ebene (von drei Ebenen) meines Drilldowns zu bearbeiten.

Das Problem in meinem Fall ist, dass VC ein UIViewController war (der eine View enthielt, die eine TableView enthielt). Ich habe stattdessen VC einen UITableViewController (der eine TableView enthielt) gemacht. Die UITableViewController-Klasse übernimmt nach der Rückkehr von einem Push automatisch die Entmarkierung der Tabellenzelle. Die zweite Antwort auf den Beitrag " Problem mit deselectRowAtIndexPath in tableView " gibt eine vollständigere Antwort auf dieses Problem.

Das Problem trat für den Root-Viewcontroller nicht auf, da beim Erstellen der App als "Navigations-basierte App" in XCode der resultierende Root-Viewcontroller bereits in der Unterklasse UITableViewController erstellt wurde.

Wenn keine davon für Sie geeignet ist, sollten Sie diese Problemumgehung in Betracht ziehen:

Verwenden Sie ein Abwicklungssegment, um aufzurufen:

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

Warum das machen? In erster Linie, wenn Sie Schwierigkeiten haben, den Deaktivierungscode zum richtigen Zeitpunkt auszuführen. Ich hatte Probleme damit, auf dem viewWillAppear nicht zu funktionieren, also funktionierte der Abwickelvorgang viel besser.

Schritte:

  1. Schreibe das Abwicklungssegment (oder füge es von oben ein) in deine erste VC (die mit der Tabelle)
  2. Gehe zum 2. VC. Ziehen Sie bei gedrückter Strg-Taste von der Schaltfläche Cancel/Done/Etc, die Sie zum Deaktivieren von VC verwenden, und ziehen Sie sie auf das Beendigungssymbol oben.
  3. Wählen Sie das Abwickelsegment aus, das Sie in Schritt 1 erstellt haben

    Viel Glück.

1
Dave G

Ich verwende Core Data, also war der Code, der für mich funktionierte, eine Kombination von Ideen aus verschiedenen Antworten in Swift:

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

wenn die Zelle nach dem Berühren markiert bleibt, können Sie die UITabelView-Methode aufrufen.

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

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

}

Oder Sie können die folgende Methode verwenden und sie gemäß Ihren Anforderungen ändern.

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

Xcode 10, Swift 4

Ich hatte das gleiche Problem und stellte fest, dass ich einen leeren Aufruf von viewWillAppear unten in meinem tableViewController hinterlassen habe. Nachdem ich die leere Überschreibungsfunktion entfernt hatte, blieb die Zeile bei der Rückkehr zur tableView-Ansicht nicht mehr hervorgehoben.

problem func

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

das entfernen der leeren funktion hat mein problem gelöst.

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

Für Swift 3: .__ würde ich es vorziehen, es in viewDidDisappear zu verwenden

Definieren:-

    var selectedIndexPath = IndexPath()

In viewDidDisappear: -

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

In didSelectRowAtIndexPath: -

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

Ich hatte das gleiche Problem schon lange, falls sich jemand anderes dagegen wehren sollte:

Werfen Sie einen Blick auf Ihr -tableView: cellForRowAtIndexPath: und sehen Sie, ob Sie Zellen erstellen oder eine "Wiederverwendungskennung" verwenden. Stellen Sie in letzterem Fall sicher, dass Ihre Tabelle in IB über eine Zelle mit dieser Kennung verfügt. Wenn Sie keine Wiederverwendungskennung verwenden, erstellen Sie einfach für jede Zeile eine neue Zelle.

Dies sollte Ihrer Tabelle dann die erwartete 'ausgewählte Zeile einblenden' beim Erscheinen geben.

0
LearningAsIGo

Verwenden Sie diese Methode in der UITableViewCell-Klasse 

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

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