2010-03-02 3 views
25

Je sais que cette question a déjà été posée, et j'ai jeté un coup d'oeil à la réponse à this question. Cependant, je suis encore confus quant à la façon d'implémenter la réorganisation avec un UITableView dans un projet de données de base. Ce que je sais, c'est que j'ai besoin d'un attribut "displayOrder" dans mon entité pour suivre l'ordre des éléments, et j'ai besoin d'énumérer tous les objets dans les résultats récupérés et de définir leur attribut displayOrder.UITableView Core réorganisation des données

Dans le code donné dans la question à laquelle je suis lié, la méthode delegate table view appelle une méthode comme celle-ci [self FF_fetchResults];, et le code de cette méthode n'est pas donné, il est donc difficile de dire exactement.

Existe-t-il un exemple de code qui le démontre? Ce serait plus simple à regarder que de partager de gros morceaux de code.

Merci

+0

Avez-vous essayé le code lié? Si vous utilisez un contrôleur de résultats récupéré, vous n'avez peut-être rien à faire. Cette méthode récupère à nouveau les objets (maintenant que le tri a changé). – gerry3

+0

Merci, je vais essayer. Est-il nécessaire de récupérer les objets après que l'ordre a changé? – indragie

+0

Vous ne devriez pas avoir besoin de si vous utilisez un contrôleur de résultats récupérés (et avoir un code de plaque de chaudière pour mettre à jour la vue de table lorsque le contrôleur de résultats récupérés change). – gerry3

Répondre

56

Je ne suis pas sûr quelle partie vous rencontrez des problèmes avec (basé sur les commentaires) ... mais voici ma suggestion. DisplayOrder est simplement un attribut simple sur une classe NSManagedObject. Si vous pouvez enregistrer un objet géré, vous pourrez terminer cette fonctionnalité. Permet de prendre d'abord simple NSManagedObject:

@interface RowObj : NSManagedObject 
{ 
} 

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

Ensuite, nous devons avoir une copie locale des données affichées dans le tableview. J'ai lu les commentaires que vous avez faits et je ne suis pas vraiment sûr si vous utilisez le FetchedResultsController ou non. Ma suggestion serait de commencer simple et juste utiliser un tableviewcontroller normal où vous mettez à jour les données de la ligne chaque fois qu'un utilisateur change l'ordre d'affichage ... puis enregistrez la commande lorsque l'utilisateur a fini d'éditer.

L'interface pour cette tableviewcontoller ressemblerait à ceci:

@interface MyTableViewController : UITableViewController { 
    NSMutableArray *myTableViewData; 
} 

@property(nonatomic,retain) NSMutableArray *myTableViewData; 

@end 

Ensuite, nous avons besoin de charger les données de la vue de la table dans la méthode viewWillAppear:

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

Il y a 2 choses qui se passent ici ... (je vais expliquer le editButtonItem plus tard) le premier est que nous devons obtenir nos données de CoreData. Quand je dois faire ceci j'ai une sorte d'aide (appelez cela ce que vous voulez) l'objet fait le travail. Une méthode de recherche typique ressemblerait à ceci:

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

Maintenant que vous avez vos données, vous pouvez maintenant attendre que l'utilisateur d'éditer la table. C'est là que le [self editButtonItem] entre en jeu. Il s'agit d'une fonction intégrée qui renvoie un élément de bouton de barre qui fait basculer son titre et son état associé entre Modifier et Terminé. Lorsque l'utilisateur clique sur ce bouton, il appelle la méthode setEditing: animated:

Pour mettre à jour l'ordre d'affichage, vous devez remplacer la méthode setEditing de la classe UITableViewController. Il devrait ressembler à ceci:

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

Nous ne devons pas faire quoi que ce soit lorsque l'utilisateur est en mode d'édition ... nous voulons seulement sauver une fois qu'ils ont appuyé sur le bouton « Terminé ». Lorsqu'un utilisateur fait glisser une ligne dans votre table, vous pouvez mettre à jour votre ordre d'affichage en redéfinissant les canMoveRowAtIndexPath et les méthodes 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]; 
} 

Encore une fois, la raison pour laquelle je ne met pas à jour la valeur displayorder est ici parce que l'utilisateur est toujours en Mode édition...nous ne savons pas si l'utilisateur a fini d'éditer ET ils pourraient même annuler ce qu'ils ont fait en ne touchant pas le bouton "Terminé".

EDIT

Si vous souhaitez supprimer une ligne que vous devez passer outre tableView: commitEditingStyle: forRowAtIndexPath et faire quelque chose comme ceci:

- (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

Merci pour la réponse détaillée, je vais essayer cela. – indragie

+0

Bien sûr, laissez-moi savoir si vous avez des problèmes ... c'est en gros mot-4-mot d'une implémentation de travail de l'une de mes applications, donc il devrait vous aider à le faire. –

+0

Qu'en est-il de la suppression de lignes? Y at-il quelque chose de spécial qui doit être fait là-bas pour travailler avec cela? – indragie

Questions connexes