2010-03-02 22 views
25

So che questa domanda è stata posta prima e ho dato un'occhiata alla risposta a this question. Tuttavia, sono ancora confuso su come implementare il riordino con un UITableView in un progetto Core Data. Quello che so è che ho bisogno di avere un attributo "displayOrder" nella mia Entity per tracciare l'ordine degli oggetti, e ho bisogno di enumerare attraverso tutti gli oggetti nei risultati recuperati e impostare il loro attributo displayOrder.UITableView Core Data riordino

Nel codice indicato nella domanda a cui ho collegato, il metodo delegate della vista tabella chiama un metodo come questo [self FF_fetchResults]; e il codice per tale metodo non viene fornito, quindi è difficile dire quale sia esattamente.

C'è qualche codice di esempio che lo dimostra? Sarebbe più semplice da guardare rispetto alla condivisione di grossi pezzi di codice.

Grazie

+0

Hai provato il codice legato? Se si utilizza un controller dei risultati recuperato, potrebbe non essere necessario fare nulla. Quel metodo sta semplicemente recuperando gli oggetti (ora che l'ordinamento è cambiato). – gerry3

+0

Grazie, ci proverò. È necessario recuperare nuovamente gli oggetti dopo che l'ordine è cambiato? – indragie

+0

Non dovrebbe essere necessario se si utilizza un controller dei risultati recuperato (e il codice della piastra della caldaia è aggiornato per aggiornare la vista tabella quando il controller dei risultati recuperato cambia). – gerry3

risposta

56

non sono sicuro quale parte si hanno problemi con (sulla base dei commenti) ... ma qui è il mio suggerimento. DisplayOrder è solo un semplice attributo su una classe NSManagedObject. Se è possibile salvare un oggetto gestito, sarà possibile completare questa funzione. Lascia in primo luogo prendere una semplice NSManagedObject:

@interface RowObj : NSManagedObject 
{ 
} 

@property (nonatomic, retain) NSString *rowDescription; 
@property (nonatomic, retain) NSNumber *displayOrder; 

Avanti, abbiamo bisogno di avere copia locale dei dati che vengono visualizzati nel Tableview. Ho letto i commenti che hai fatto e non sono sicuro se stai usando FetchedResultsController o meno. Il mio suggerimento sarebbe di iniziare in modo semplice e utilizzare solo un normale tableviewcontroller in cui aggiorni i dati delle righe ogni volta che un utente modifica l'ordine di visualizzazione ... quindi salva l'ordine quando l'utente ha terminato le modifiche.

L'interfaccia di questo tableviewcontoller sarebbe simile a questa:

@interface MyTableViewController : UITableViewController { 
    NSMutableArray *myTableViewData; 
} 

@property(nonatomic,retain) NSMutableArray *myTableViewData; 

@end 

Avanti, abbiamo bisogno di caricare i dati la visualizzazione della tabella nel metodo viewWillAppear:

- (void)viewWillAppear:(BOOL)animated { 
    myTableViewData = [helper getRowObjects]; // insert method call here to get the data 
    self.navigationItem.leftBarButtonItem = [self editButtonItem]; 
} 

Ci sono 2 cose che accadono qui ... (Spiegherò più tardi editButtonItem) il primo è che dobbiamo ottenere i nostri dati da CoreData. Quando devo fare questo ho una sorta di aiuto (chiamalo come vuoi) oggetto fare il lavoro. Un tipico metodo find sarebbe simile a questa:

- (NSMutableArray*) getRowObjects{ 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"RowObj" inManagedObjectContext:[self managedObjectContext]]; 
    [request setEntity:entity]; 

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    [request setSortDescriptors:sortDescriptors]; 
    [sortDescriptors release]; 
    [sortDescriptor release]; 

    NSError *error; 
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy]; 
    if (mutableFetchResults == nil) { 
     // Handle the error. 
    } 
    [request release]; 
    return mutableFetchResults; 
} 

Ora che avete i dati, è ora possibile attendere che l'utente per modificare la tabella. È qui che entra in gioco [self editButtonItem]. Questa è una funzione incorporata che restituisce un elemento della barra che alterna il titolo e lo stato associato tra Modifica e Fine. Quando l'utente preme quel pulsante, invocherà il setEditing: animato: metodo:

Per aggiornare l'ordine di visualizzazione è necessario sovrascrivere il metodo setEditing nella classe UITableViewController. Esso dovrebbe essere simile a questo:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated { 
    [super setEditing:editing animated:animated]; 
    [myTableView setEditing:editing animated:animated]; 
    if(!editing) { 
     int i = 0; 
     for(RowObj *row in myTableViewData) { 
      row.displayOrder = [NSNumber numberWithInt:i++]; 
     } 
     [helper saveManagedObjectContext]; // basically calls [managedObjectContext save:&error]; 
    } 
} 

Non abbiamo nulla a che fare quando l'utente è in modalità di modifica ... vogliamo solo salvare una volta che hanno premuto il pulsante "Done". Quando un utente trascina una riga nella tabella è possibile aggiornare il vostro ordine di visualizzazione sovrascrivendo i metodi canMoveRowAtIndexPath e moveRowAtIndexPath:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 
    return true; 
} 

(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { 

    RowObj *row = [myTableViewData objectAtIndex:sourceIndexPath.row]; 
    [myTableViewData removeObjectAtIndex:sourceIndexPath.row]; 
    [myTableViewData insertObject:row atIndex:destinationIndexPath.row]; 
} 

Anche in questo caso, la ragione non aggiorno il valore displayorder qui è perché l'utente è ancora in modalità Modifica...non sappiamo se l'utente ha finito di modificare E potrebbero persino cancellare ciò che hanno fatto non premendo il pulsante "Fatto".

EDIT

Se si desidera eliminare una riga è necessario eseguire l'override tableView: commitEditingStyle: forRowAtIndexPath e fare qualcosa del genere:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the managed object at the given index path. 
     RowObj *row = [myTableViewData objectAtIndex:indexPath.row]; 
     [helper deleteRow:row]; 

     // Update the array and table view. 
     [myTableViewData removeObjectAtIndex:indexPath.row]; 
     [myTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; 
    } 
} 
+0

Grazie per la risposta dettagliata, ci proverò. – indragie

+0

Certo, fammi sapere se hai qualche problema ... questa è fondamentalmente parola-parola da un'implementazione funzionante da una delle mie app quindi dovrebbe aiutarti a farlo. –

+0

E riguardo l'eliminazione delle righe? C'è qualcosa di speciale che deve essere fatto lì per lavorare con questo? – indragie