36 Stimmen

Speichern der ausgewählten Zeile in UITableView nach ReloadData

Ich schreibe benutzerdefinierte Jabber-Client in iphone.

Yo uso xmppframework als Motor.

Und ich habe UITableViewController mit NSMutableArray für aktuelle Kontaktliste.

Wenn ich erhalten (oder jemand ändern es Inhalt) Dienstplan (aka Kontaktliste) ich möchte UITableView Elemente (hinzufügen/entfernen/ändern) ändern. Also, wenn Benutzer Arbeit mit listView zu Zeit, wenn Liste Updates von

[items addObject:newItem];
[self.tableView reloadData];

Benutzer hat aktuelles Auswahlelement verloren.

Also, meine Frage ist howto speichern (wenn möglich, ich meine, wenn gegebenes ausgewähltes Element nicht entfernt) aktuelle auswählen Element nach reloadData?

Vielen Dank.

3voto

Kevin Delord Punkte 2420

Unter iOS 9.3 und Swift 2.x musste ich einfach die Funktion auf der Hauptstrang :)

self.tableView?.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)

1voto

Adam Wallner Punkte 2036

Das funktioniert bei mir:

NSIndexPath *indexPath = [table indexPathForSelectedRow];
[table reloadData];
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self.table selectRowAtIndexPath:indexPath animated:YES
                              scrollPosition:UITableViewScrollPositionNone];
});

Der Trick besteht darin, selectRowAtIndexpath ein wenig später laufen zu lassen. Der obige Code ist eine Xcode-Vorlage, die Sie auswählen können, wenn Sie mit dem Schreiben beginnen dispatch_after .

1voto

Ezeki Punkte 1519

Dies ist eine Lösung für den Fall, dass Sie Tabellenaktualisierungen vornehmen und die Auswahl beibehalten möchten:

    NSIndexPath* pathToSelect = [self.tableView indexPathForSelectedRow];
    if (pathToSelect && newRows) {
        int row = pathToSelect.row;
        for (NSIndexPath* path in newRows) {
            if (path.section == pathToSelect.section && path.row <= pathToSelect.row) {
                row++;
            }
        }
        pathToSelect = [NSIndexPath indexPathForRow:row inSection:pathToSelect.section];
    }

    [self.tableView beginUpdates];
    if (reloadRows) [self.tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation:UITableViewRowAnimationFade];
    if (newSections) [self.tableView insertSections:newSections withRowAnimation:UITableViewRowAnimationFade];
    if (newRows) [self.tableView insertRowsAtIndexPaths:newRows withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];

    if (pathToSelect) {
        [self.tableView selectRowAtIndexPath:pathToSelect animated:NO scrollPosition:UITableViewScrollPositionNone];
    }

1voto

Basil Punkte 418

Bearbeiten:

Nach dem Test, funktioniert es nicht immer!

der Grund ist, dass sich der Index ändern kann!

Der richtige Weg ist also
neue Variable erstellen

var currentIndex : IndexPath?

und bei didSelectRow

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        currentIndex = indexPath
}

dann ändern Sie die Funktion in

 func reloadTableView() {
        let indexPaths = tableview.indexPathsForSelectedRows
        if let currentIndex = self.currentIndex {
        self.tableview.reloadRows(at: [currentIndex], with: .fade)
        for path in indexPaths ?? [] {
            tableview.selectRow(at: path, animated: false, scrollPosition: .none)
            }}
    }

\==========

@marmor Antwort funktioniert

Dies ist eine Swift-Version seines Codes

Swift 4.2.3

func reloadTableView() {
        let indexPaths = tableView.indexPathsForSelectedRows
        tableView.reloadData()
        for path in indexPaths ?? [] {
            tableView.selectRow(at: path, animated: false, scrollPosition: .none)
        }
    }

1voto

Fonix Punkte 11001

Viele dieser Antworten sind im Grunde mit Hacks, um die Zeile, die zuvor hervorgehoben wurde, indem Sie herausfinden, was die zuvor ausgewählte Zeile aus der Tabelle Ansicht, die wie ein schlechter Weg, um es zu gehen scheint, weil in der Regel, wenn Ihr tableview neu lädt, gibt es eine Änderung in den Daten, die die tableview bevölkert ist neu auswählen.

Wählen Sie also lieber die Zeile auf der Grundlage Ihrer Daten neu aus

let data = ["some", "array", "of", "data"]
let selected = "of" // this should be populated from didSelectRowAt indexPath:

tableView.reloadData()

if let index = data.firstIndex(of: selected) {
  tableView.selectRow(at: IndexPath(row: index, section: 0), animated: false, scrollPosition: .none) // the "of" row should now be highlighted, regardless if the data changed order
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X