'Ungültige Aktualisierung: Ungültige Anzahl von Zeilen in Abschnitt 0

70

Ich habe alle diesbezüglichen Beiträge gelesen und habe immer noch einen Fehler:

'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

Hier sind die Details:

in .hIch habe eine NSMutableArray:

@property (strong,nonatomic) NSMutableArray *currentCart;

In .mmeinem numberOfRowsInSectionAussehen so:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.


    return ([currentCart count]);

}

So aktivieren Sie das Löschen und Entfernen des Objekts aus dem Array:

// Editing of rows is enabled
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {

        //when delete is tapped
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

        [currentCart removeObjectAtIndex:indexPath.row];


    }
}

Ich dachte, wenn meine Anzahl von Abschnitten von der Anzahl des Arrays abhängt, das ich bearbeite, würde dies die richtige Anzahl von Zeilen sicherstellen? Kann man das nicht tun, ohne die Tabelle neu laden zu müssen, wenn man eine Zeile löscht?

user3085646
quelle

Antworten:

157

Sie müssen das Objekt aus Ihrem Datenarray entfernen, bevor Sie es aufrufen deleteRowsAtIndexPaths:withRowAnimation:. Ihr Code sollte also folgendermaßen aussehen:

// Editing of rows is enabled
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {

        //when delete is tapped
        [currentCart removeObjectAtIndex:indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

Sie können Ihren Code auch ein wenig vereinfachen, indem Sie die Verknüpfung zum Erstellen von Arrays verwenden @[]:

[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
Rückgängig machen
quelle
Unglaublich, dass ich diese fehlerhafte Logik übersehen habe. Einfache Lösung und ich wurde verrückt, als ich versuchte herauszufinden, ob meine Zählung falsch übergeben wurde. Vielen Dank.
user3085646
Kein Problem! Ich habe unzählige Male genau das Gleiche getan, und deshalb hatte ich eine ziemlich gute Vorstellung davon, was das Problem war.
Rückgängig machen
1
Was ist, wenn ich die Zeilennummer buchstäblich zurückgebe? wie als Schalter (Abschnitt) {Fall 0: Rückgabe 3; Unterbrechung; Fall 1: Rückgabe 5; Unterbrechung; Fall 2: Rückgabe 2; Unterbrechung; } return 0; Es gibt kein Modellarray, das ich einrichte. Ich lerne gerade die Tabellenansicht. Ich habe das Problem gefunden und versuche, modelarray zu erstellen und removeObjectAtIndex zu löschen, habe aber immer noch den gleichen Fehler.
Alix
Warum ist das Array so mit der dataSource verbunden? Hat deleteRowsAtIndexPathsrufen Sie einfach automatisch reload? und sieht dann eine Nichtübereinstimmung?
Honig
14

Swift-Version -> Entfernen Sie das Objekt aus Ihrem Datenarray, bevor Sie es aufrufen

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        print("Deleted")

        currentCart.remove(at: indexPath.row) //Remove element from your array 
        self.tableView.deleteRows(at: [indexPath], with: .automatic)
    }
}
Alejandra Vidal Ortiz
quelle
4

In meinem Fall war das Problem, dass numberOfRowsInSectionnach dem Aufruf eine ähnliche Anzahl von Zeilen zurückgegeben wurde tableView.deleteRows(...).

Da dies in meinem Fall das erforderliche Verhalten war, habe ich letztendlich angerufen, tableView.reloadData()anstatt tableView.deleteRows(...)in Fällen, in denen numberOfRowsInSectionnach dem Löschen einer Zeile dieselbe bleibt.

Haseeb Iqbal
quelle
0

Hier ist ein Code von oben, der mit dem tatsächlichen Aktionscode hinzugefügt wurde (Punkt 1 und 2).

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { _, _, completionHandler in

        // 1. remove object from your array
        scannedItems.remove(at: indexPath.row)
        // 2. reload the table, otherwise you get an index out of bounds crash
        self.tableView.reloadData()

        completionHandler(true)
    }
    deleteAction.backgroundColor = .systemOrange
    let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
    configuration.performsFirstActionWithFullSwipe = true
    return configuration
}
7RedBits.com
quelle