2009-01-28 2 views

Antwort

14

Hier machen wir unser schweres Heben.

- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
     toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row); 
    // fetch the object at the row being moved 
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

    // remove the original from the data structure 
    [rows removeObjectAtIndex:fromIndexPath.row]; 

    // insert the object at the target row 
    [rows insertObject:r atIndex:toIndexPath.row]; 
    NSLog(@"result of move :\n%@", [self rows]); 
} 

Da dies ein einfaches Beispiel ist, lassen Sie alle Zeilen beweglich sein.

- (BOOL)tableView:(UITableView *)tableView 
canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 
    return YES; 
} 
+0

Wenn removeObjectAtIndex aufgerufen wird, reduziert dies die Referenzanzahl des Objekts (und möglicherweise dazu führen, dass es freigegeben wird)? Ich denke, ExchangeObjectAtIndex: withObjectAtIndex: (wie von @dreamlax vorgeschlagen) ist sicherer. –

+0

BTW, wenn Sie Ihre eigene Frage beantworten, denke ich, es ist gute Form, es zu einem Wiki zu machen. –

+0

@KristopherJohnson 'exchangeObjectAtIndex: withObjectAtIndex:' ist in diesem Fall nicht geeignet. Es hat eine andere Semantik als die von 'tableView: moveRowAtIndexPath: toIndexPath:'. – Benjohn

0

NSMutableArray hat eine Methode namens exchangeObjectAtIndex:withObjectAtIndex:.

+3

Ich habe dieses versucht, aber das Verhalten ist anders.Die Tabelle tauscht die Zeilen nicht aus, entfernt eine Zeile und fügt sie an anderer Stelle ein. Wenn ich diese Methode verwende, sind die Tabelle und der Backing Store bei jeder Bewegung nicht mehr synchron. –

11

Keines der obigen funktioniert. Im ursprünglichen geposteten Code stürzt die Tabellenansicht ab, weil sie die Daten entfernt, die noch verwendet werden, und selbst nachdem sie korrigiert wurden, würde das Array aufgrund der Art und Weise, wie die Tabelle eine 'Neuanordnung' vornimmt, nicht die richtigen Daten haben.

exchangeObjectAtIndex: withObjectAtIndex: ein Array für Neuanordnung nach nicht funktionieren, wie ein Tableview seine eigene implementiert

Warum neu anordnen? Da, wenn der Benutzer eine Tabellenzelle auswählt, um sie neu anzuordnen, wird diese Zelle NICHT mit der Zelle vertauscht, in die sie verschoben wird. Die ausgewählte Zelle wird in den neuen Zeilenindex eingefügt, und anschließend wird die ursprüngliche Zelle entfernt. So sieht es zumindest für den Benutzer aus.

Lösung: Aufgrund der Art, wie die Tabellenansicht eine Neuanordnung implementiert, müssen wir eine Überprüfung durchführen, um sicherzustellen, dass wir die richtige Zeile hinzufügen und entfernen. Dieser Code, den ich zusammensetze, ist einfach und funktioniert perfekt für mich.

die Original geschrieben Codedaten als Beispiel:


- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)fromIndexPath 
     toIndexPath:(NSIndexPath *)toIndexPath 
{ 
    NSLog(@"move from:%d to:%d", fromIndexPath.row, toIndexPath.row); 
    // fetch the object at the row being moved 
    NSString *r = [rows objectAtIndex:fromIndexPath.row]; 

     // checks to make sure we add and remove the right rows 
    if (fromIndexPath.row > toIndexPath.row) { 

     // insert the object at the target row 
     [rows insertObject:r atIndex:toIndexPath.row]; 

     // remove the original from the data structure 
     [rows removeObjectAtIndex:(fromIndexPath.row + 1)]; 
    } 
    else if (fromIndexPath.row < toIndexPath.row) { 

     // insert the object at the target row 
     [rows insertObject:r atIndex:(toIndexPath.row + 1)]; 

     // remove the original from the data structure 
     [rows removeObjectAtIndex:(fromIndexPath.row)]; 

    } 

} 

Wenn Sie ein paar Minuten Zeit nehmen und werfen Sie einen Blick auf, was während eines neu anordnen zu einem Tableview geschieht Sie werden verstehen, warum wir das 1 ist, wo wir hinzufügen hat getan.

Ich bin ziemlich neu zu xcode, also weiß ich, es gibt wahrscheinlich eine einfachere Möglichkeit, dies zu tun, oder der Code kann wahrscheinlich vereinfacht werden .... Nur versuchen, zu helfen, wo ich kann, weil es mich ein paar genommen hat Stunden, um das herauszufinden. Hoffe das spart jemandem etwas Zeit!

+1

Dies ist die richtige Antwort für die Kombination von TableView und NSMutableArray – wayneh

+1

Thanx Wiz. Dein Code funktioniert perfekt und macht auch Sinn. – Ali

5

Laut Apples Dokumentation, und meine eigene Erfahrung, diese einige einfache Code, der recht gut funktioniert:

NSObject *tempObj = [[self.rows objectAtIndex:fromIndexPath.row] retain]; 
[self.rows removeObjectAtIndex:fromIndexPath.row]; 
[self.rows insertObject:tempObj atIndex:toIndexPath.row]; 
[tempObj release]; 
+0

Schöne Antwort. Dein ist das Korrekteste von allen. Danke, Mann! – GeneCode

0

diese Diskussion gefunden, nachdem mein Kopf gegen eine einfache Implementierung zu brechen ... Michael Berding Lösung ist die Am besten für mich, den Apple-Weg, nur daran denken, zu entfernen und zu lösen, wenn Sie ARC verwenden. Also, eine prägnantere Lösung

NSObject *tempObj = [self.rows objectAtIndex:fromIndexPath.row]; 
[self.rows removeObjectAtIndex:fromIndexPath.row]; 
[self.rows insertObject:tempObj atIndex:toIndexPath.row];