TableViewController moveRowAtIndexPath

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • TableViewController moveRowAtIndexPath

    Hallo Zusammen,

    ich habe einen TableViewController, bei dem der Nutzer die Reihenfolge der Einträge per drag and drop ändern kann. Das funktioniert ganz hervorragend mit:

    Quellcode

    1. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    2. NSInteger sourceRow = fromIndexPath.row;
    3. NSInteger destRow = toIndexPath.row;
    4. Criterion *changedCriterion = [self.decision.criterionArray objectAtIndex:sourceRow];
    5. [self.decision.criterionArray removeObjectAtIndex:sourceRow];
    6. [self.decision.criterionArray insertObject:changedCriterion atIndex:destRow];
    7. }


    Jetzte möchte ich jedoch, dass das oberste Objekt eine "1." vor dem eigentlichen Bezeichner anzeigt und das n-te Objekte halt z.B. "6."
    Hierzu ergänzte ich am Ende der Methode moveRowAtIndexPath:

    Quellcode

    1. for (int i=0; i < [self.decision.criterionArray count]; i++) {
    2. NSIndexPath *newPath = [NSIndexPath indexPathForRow:i inSection:0];
    3. UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:newPath];
    4. Criterion *criterion = [self.decision.criterionArray objectAtIndex:i];
    5. criterion.priotity = [self.decision.criterionArray count]-newPath.row;
    6. criterion.showPriotity = newPath.row+1;
    7. cell.textLabel.text = [NSString stringWithFormat:@"%i. %@", criterion.showPriotity, criterion.name];
    8. }


    Leider geht cell.textLabel.text = ... total schief, da mir [self.tableView cellForRowAtIndexPath:newPath]; die Reihenfolge vor der Sortierung zurückgibt.
    Was mache ich falsch bzw. wo ist mein Denkfehler?

    Vielen Dank.
  • ioscampus schrieb:

    Weil er es in der Methode wie sie jetzt ist ja auch nicht macht.

    Warum sollte eine System.Methode sein Verhalten ändern, wenn Du Deinen Code anpasst?

    ioscampus schrieb:

    Es werden die Zellen in der Reihenfolge VOR der Umsortierung geliefert.

    Na und? Das kann Dir doch egal sein. Dann weist Du den Labels eben die vertauschten Werte zu.
    „Meine Komplikation hatte eine Komplikation.“
  • Und zu Hause ist mir auch wieder aufgefallen, warum ich alle Zellen bearbeiten muss. Der Nutzer kann natürlich die 6. Zelle an Position 2 schieben, wodurch sich auch der Index der Zellen dazwischen verändert.

    Ich finde das Phänomen immer noch komisch. Mit moveRowAtIndexPath sagt mir das System doch "hey der User hat die Reihenfolge der Zellen verschoben, pass mal bitte deine Datenbasis an." Wenn ich nun jedoch durch alle Zellen durch iteriere, dann liefert das System mir die Reihenfolge vor der Umsortierung. Das fühlt sich für mich wie ein Fehler an.

    Oder gibt es noch eine Methode die später aufgerufen wird und wo die Umsortierung abgeschlossen ist? Soetwas wie moveRowAtIndexPathHasFinished?
  • wolf_10de schrieb:

    Wenn ich das richtig verstanden hab ist dein Problem, dass du dein Model ändern musst, bzw. es nix von der Änderung mitbekommt


    Nein, mein Model ist up to date. Das Label der Zelle ist es nach der Umsortierung nicht. Mein Tabelle ist z.B.:

    1. BlaBlub
    2. Test
    3. someThingAwesome

    Wenn ich nun Nummer 3 an Pos 1 schiebe sieht die Tabelle so aus:

    3. someThingAwesome
    1. BlaBlub
    2. Test

    Ich möchte, dass sich die Nummerierung mit ändert. Daher durchlaufe ich alle Zellen in moveRowAtIndexPath, um das Label zu aktualisieren. Leider liefert cellForRowAtIndexPath die Reihenfolge vor der Umsortierung.
  • Du könntest dir die Zahl aus den Daten statt der UI holen.
    Wenn du der Zelle eine Property zuweist, anhand der du einfach identifizieren kannst zu welchem Datensatz in deinem Array sie gehört, sollte das recht einfach gehen.

    Nehmen wir mal an du gibst deiner Zelle eine Property id representedObject.
    In cellForRow... weist du dies über cell.representedObject = [self.decision.criterionArray objectAtIndex:indexPath.row] zu.

    in moveRowAtIndexPath... kannst du nach deinem remove/insert im Datenmodell dann über die visibleCells iterieren und die neue Zahl für den Titel über
    [self.decision.criterionArray indexOfObject:cell.representedObject] herausbekommen.

    Könnte man sicher noch optimieren indem man man nur die Zellen im geänderten Bereich aktualisiert, sowie das Array auch gezielter über indexOfObject:inRange: durchsucht.
  • Endlich hatte ich die Zeit mich dem Problem noch einmal zu widmen - es klappt nun ganz hervorragend.

    Quellcode

    1. for (int i=0; i < [self.decision.criterionArray count]; i++) {
    2. NSIndexPath *newPath = [NSIndexPath indexPathForRow:i inSection:0];
    3. CriterionCell *cell = (CriterionCell*)[self.tableView cellForRowAtIndexPath:newPath];
    4. Criterion *criterion = cell.representedObject;
    5. criterion.priotity = [self.decision.criterionArray indexOfObject:criterion];
    6. criterion.showPriotity = criterion.priotity+1;
    7. cell.textLabel.text = [NSString stringWithFormat:@"%i. %@", criterion.showPriotity, criterion.name];
    8. // NSLog(@"cell %i, content: %@ ", i, cell.textLabel.text);
    9. }


    Ehrlich gesagt fühlt es sich trotzdem wie ein Workaround an und ich würde behaupten das Standardverhalten des Frameworks ist falsch.
    Vielen Dank für eure Hilfe.
    :)