2009-01-28 8 views

Odpowiedz

14

Tutaj robimy nasze ciężkie podnoszenie.

- (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]); 
} 

Ponieważ jest to podstawowy przykład, pozwól, aby wszystkie wiersze były ruchome.

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

Kiedy removeObjectAtIndex nazywa, będzie to zmniejszyć liczbę odwołań danego obiektu (a może spowodować, że być zwalniane)? Myślę, że obiekt exchangeObjectAtIndex: withObjectAtIndex: (zgodnie z sugestią @dreamlax) jest bezpieczniejszy. –

+0

BTW, jeśli odpowiadasz na własne pytanie, myślę, że to jest dobra forma, aby zrobić z niego wiki. –

+0

@KristopherJohnson 'exchangeObjectAtIndex: withObjectAtIndex:' nie nadaje się w tym przypadku. Ma inną semantykę niż te wymagane przez 'tableView: moveRowAtIndexPath: toIndexPath:'. – Benjohn

0

NSMutableArray ma metodę zwaną exchangeObjectAtIndex:withObjectAtIndex:.

+3

Próbowałem tego, ale zachowanie jest inne.Tabela nie wymienia rzędów, usuwa jeden wiersz, a następnie wstawia go w innym miejscu. Jeśli skorzystam z tej metody, stół i sklep podkładowy będą bardziej niezsynchronizowane z każdym ruchem. –

11

Żadne z powyższych nie zadziała. W oryginalnym opublikowanym kodzie widok tabeli ulegnie awarii, ponieważ usunie dane, które będą nadal w użyciu, a nawet po ich skorygowaniu, tablica nie będzie miała poprawnych danych ze względu na sposób, w jaki tabela "przestawia się".

exchangeObjectAtIndex: withObjectAtIndex: nie będzie działać na rozmieszczanie tablicę według jak tableview realizuje własny rozmieszczanie

Dlaczego? Ponieważ gdy użytkownik wybierze komórkę tabeli, aby zmienić jej kolejność, komórka NIE zostanie zamieniona z komórką, do której jest przenoszona. Wybrana komórka zostanie wstawiona do indeksu nowego wiersza, a następnie oryginalna komórka zostanie usunięta. Przynajmniej tak wygląda dla użytkownika.

Rozwiązanie: Ze względu na sposób, w jaki widok stołu implementuje przegrupowanie, musimy wykonać kontrolę, aby upewnić się, że dodaliśmy i usunięto prawy wiersz. Ten kod, który zestawiłem, jest prosty i działa idealnie dla mnie.

Korzystanie z oryginalnych danych kodu jako przykład:


- (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)]; 

    } 

} 

Jeśli wziąć kilka chwil i przyjrzeć się temu, co dzieje się z tableview podczas Przegrupuj będzie zrozumieć, dlaczego dodajemy 1 gdzie my zrobił.

Jestem całkiem nowy w Xcode, więc wiem, że jest prawdopodobnie łatwiejszy sposób na zrobienie tego, lub kod może być prawdopodobnie uproszczony ... Po prostu próbuję pomóc gdzie mogę, ponieważ zajęło mi to kilka godzin, aby to zrozumieć. Mam nadzieję, że to kogoś oszczędza!

+1

To jest poprawna odpowiedź dla kombinacji TableView i NSMutableArray – wayneh

+1

Thanx Wiz. Twój kod działa idealnie i ma sens. – Ali

5

Według dokumentacji Apple i własnego doświadczenia, to jest jakiś prosty kod, który działa całkiem dobrze:

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

Dobra odpowiedź. Twój jest najbardziej poprawny ze wszystkich. Dzięki! – GeneCode

0

Znaleziony tę dyskusję po zerwaniu głowę na prostą realizację ... rozwiązanie jest Michael Berding najlepiej dla mnie, na sposób Apple, pamiętaj tylko, aby usunąć zachować i zwolnić podczas korzystania z ARC. Tak więc, bardziej zwięzły rozwiązanie

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