Tri d'objets d'une classe modèle contenus dans un NSArray
Eddy58
Membre
Mes projets m'amènent à présent à utiliser le tri, que je n'ai pas encore eu l'occasion d'expérimenter, et je n'ai pas trouvé de doc très explicite sur le sujet.
Je voudrais trier un NSArray, tout d'abord à chaque ajout d'un objet de ma classe modèle dans celui-ci, et ensuite répercuter les résultats dans la TableView qui affiche les données du NSArray. Dans la TableView, je voudrais aussi dédier deux colonnes pour le tri inversé soit par date dans l'une, et par ordre alphabétique dans l'autre. Chaque objet de ma classe modèle contient diverses variables d'instances NSCalendarDate et NSString.
Je me pose les questions suivantes : ???
1) Quelle méthode utiliser pour faire comprendre que je veux faire un tri par rapport à une certaine variable d'instance NSCalendarDate ou NSString de ma classe modèle ?
2) Comment se répercute le tri sur la tableview, selon le choix d'inversion choisi dans les columns headers ?
Autre précision, je n'utilise pas les bindings et ne veux pas les utiliser pour le moment...
Je voudrais trier un NSArray, tout d'abord à chaque ajout d'un objet de ma classe modèle dans celui-ci, et ensuite répercuter les résultats dans la TableView qui affiche les données du NSArray. Dans la TableView, je voudrais aussi dédier deux colonnes pour le tri inversé soit par date dans l'une, et par ordre alphabétique dans l'autre. Chaque objet de ma classe modèle contient diverses variables d'instances NSCalendarDate et NSString.
Je me pose les questions suivantes : ???
1) Quelle méthode utiliser pour faire comprendre que je veux faire un tri par rapport à une certaine variable d'instance NSCalendarDate ou NSString de ma classe modèle ?
2) Comment se répercute le tri sur la tableview, selon le choix d'inversion choisi dans les columns headers ?
Autre précision, je n'utilise pas les bindings et ne veux pas les utiliser pour le moment...
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
[tt]NSSortDecriptor* sortDesc1 = [[NSSortDescriptor alloc] initWithKey:@title ascending:YES];
NSSortDecriptor* sortDesc2 = NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];<br /><br />[myMutableArray sortUsingDescriptors:[NSArray arrayWithObjects:sortDesc1,sortDesc2,nil;
[sortDesc1 release];
[sortDesc2 release];[/tt]
C'est bien moins compliqué que je le pensais ! :P
Rien à faire dans le NSArray ou la classe modèle, c'est KVC "compliant" d'entrée et la méthode de tri trouve les accesseurs de la classe modèle comme une grande.
Par contre, pour tenter "d'économiser" du code, j'ai essayé dans IB, après avoir mis en inactif mon code qui gère les actions dans le column header, les réglages de tri dans les colonnes, en mettant la même key que dans le code, mais ça faisait rien, la petite flèche apparaissait bien, mais aucun tri. Ca doit fonctionner d'une certaine façon ?
-sortUsingSelector: qui envoie un message à un objet du tableau en utilisant le sélecteur placé en argurment comme sélecteur, et un autre élément du tableau comme argument.
-sortUsingFunction: qui appelle une fonction qui prend 2 objets à comparer comme arguments, ainsi qu'un paramètre extérieur.
Mais perso, je trouve ça assez lourd, en particulier lorsque qu'on a plusieurs critères de tri, et ça oblige à mettre du code spécifique pour chaque tri, ou presque.
http://www.cocoadev.com/index.pl?SortUsingSelector
Déterrage de thread !
Dites moi les gars, la ligne :
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObjects:sortDesc1,sortDesc2,nil]];
je ne vois pas trop ou la mettre dans ma classe modèle... ???
[tt]
// Tri dans la colonne choisie
-(void)makeTri
{
if (datesDebutsChoix==YES) // Si choix DatesDebuts alors créer l'instance descripteur de tri correspondante
{
sortDescriptor=[[NSSortDescriptor alloc] initWithKey:@dateDebut ascending:datesDebutsAscending];
}
else if (societesChoix==YES) // Sinon si choix Societes alors créer l'instance descripteur de tri correspondante
{
sortDescriptor=[[NSSortDescriptor alloc] initWithKey:@identificationSociete ascending:societesAscending selector:@selector(caseInsensitiveCompare];
}
else if
(...........autre colonnes)Â Â
  sortDescriptors=[NSArray arrayWithObject:sortDescriptor]; // Créer l'array de descripteurs de tri
tempArray=[clientsPrelevementsArray sortedArrayUsingDescriptors:sortDescriptors]; // Trier l'array clientsPrelevements avec les descripteurs et créer un array résultant temporaire
[sortDescriptor release]; // Libérer le descripteur de tri
[clientsPrelevementsArray release]; // Libérer l'ancien clientsPrelevementsArray
clientsPrelevementsArray=[tempArray mutableCopy]; // Faire pointer clientsPrelevementsArray sur le nouvel array
[clientsPrelevementsTableView reloadData]; // Mise à jour de l'affichage de la tableview clients
}
[/tt]
J'ai quelques petites questions concernant les tableView:
- j'ai une TableView qui m'affiche des Opérations (divers String, Dates, et double). Pas de soucis, à l'ajout de chaque opération dans un MutableArray qui sert de dataSource à la-dite tableView, je retrie le tableau en fonction d'une méthode par défaut, à savoir par date d'opération.
C'est là qu'une première question arrive, lorsque que j'ai vu la possibilité des @selector et de performSelector, je me suis dit que lorsque ma tableView serait triée par un des attributs d'opération, le fait d'ajouter une nouvelle opération et de trier le tableau se ferait donc selon l'odre dans lequel la tableView était déjà triée via la méthode courante selectionnée mise dans ma variable SEL. Est-ce une bonne idée une meilleure façon existe-t-elle ?
- autre point, pour l'instant, sous IB, impossible de trier une colonne de String, j'ai pourtant spécifié ma value Key operationName (avec un accesseur du même nom en plus), et choisis la méthode compare: , lorsque que je clique dans la tete de colonne, la flèche est bien soit asc ou desc, mais pas de réponse, faut-il recharger les données de la table ensuite ? Est-ce que il est nécessaire que ça soit la datasource de triée, et pas seulement "l'affichage apparant" dans la TableView ?
Sinon avec ce que j'ai lu dans un post précédent, je vais essayer en utiliser la méthode de mouseDownOnInHeaderOfTableColumn.