Chercher dans les données d'un tableau
chaps31
Membre
Hé oui encore moi qui flood avec toutes mes questions... Je vous rassure je cherche avant...
J'ai un tableau qui est le datasource d'une tableview, je veux que lorsque l'utilisateur tape dans une case l'appli "lise" les lettres et fasse un scrollView sur le nom le plus approchant de ce qui est tapé.
Je n'ai pas encore abordé les Notification donc ma question ne pose pas dessus, elle est plus simple.
Je fais des tests, j'initialise une variable NSString et je teste comme si c'était ce qu'avait tapé l'utilisateur. Bon je dois récupérer l'index du tableau et m'en servir dans ma tableview avec mon scrollView.
Pour un nom complet pas de soucis (valueForKey sur le tableau pour viser la bonne colonne et indexOfObject pour récupérer l'index). Là où ça se corse c'est lorsqu'une partie du nom est tapé, par exemple ma variable de test vaut "DUP" et je voudrais un retour du premier index de la table dont la valueforkey précédente commence par DUP, et là ... je sèche, je pensais mon salut dans indexOfObject:inrange, en pensant justement qu'il ne regarderais que le range spécifié avec un NSMakeRange, impeccable, il suffit alors que la longueur du range soit celle de la variable, départ à 0, et ça roule.... Mais je pense que indexOfObject:inrange ne fait pas ça en fin de compte... car ça ne fonctionne pas il ne trouve rien à partir d'une partie du nom...
Je m'en remet (encore) à vous... Merci.
J'ai un tableau qui est le datasource d'une tableview, je veux que lorsque l'utilisateur tape dans une case l'appli "lise" les lettres et fasse un scrollView sur le nom le plus approchant de ce qui est tapé.
Je n'ai pas encore abordé les Notification donc ma question ne pose pas dessus, elle est plus simple.
Je fais des tests, j'initialise une variable NSString et je teste comme si c'était ce qu'avait tapé l'utilisateur. Bon je dois récupérer l'index du tableau et m'en servir dans ma tableview avec mon scrollView.
Pour un nom complet pas de soucis (valueForKey sur le tableau pour viser la bonne colonne et indexOfObject pour récupérer l'index). Là où ça se corse c'est lorsqu'une partie du nom est tapé, par exemple ma variable de test vaut "DUP" et je voudrais un retour du premier index de la table dont la valueforkey précédente commence par DUP, et là ... je sèche, je pensais mon salut dans indexOfObject:inrange, en pensant justement qu'il ne regarderais que le range spécifié avec un NSMakeRange, impeccable, il suffit alors que la longueur du range soit celle de la variable, départ à 0, et ça roule.... Mais je pense que indexOfObject:inrange ne fait pas ça en fin de compte... car ça ne fonctionne pas il ne trouve rien à partir d'une partie du nom...
Je m'en remet (encore) à vous... Merci.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
- (NSRange)rangeOfString:(NSString *)aString
Il y a aussi une méthode dans NSText
- (void)scrollRangeToVisible:(NSRange)aRange
EDIT : quoique scrollRangeToVisible à l'air prometteur
A vrai dire, le pied pour ce genre de choses, c'est le Caml, mais je ne sais pas si on peut appeler du code Caml avec du C.
Pas besoin d'un tri par dichotomie ; une recherche suffit :P
qsort , heapsort, mergesort, radixsort....
sont là pour le faire, et elles fonctionnent comme sous objective-C (le hasard ?) en définissant une fonction de comparaison
int compare(const void* ptr1,const void* ptr2);
Ceci dit je crois qu'ici l'utilisation d'un NSArrayController est sans doute tout aussi Objective-C-généralisable.
À mon avis, les fonctions de tri Objective-C sont des wrappers sur ces fonctions... Mais j'ai la flemme de vérifier :P
[tt]
int i;
NSString *nomRech;
for(i=0;i<[tableclients count]; i++)
{
nomRech=[[tableclients valueForKey:@nom] objectAtIndex:i];
NSRange rangetest=[nomRech rangeOfString:vartest];
if(rangetest.location==0 && rangetest.length==[vartest length])
{
[tableView scrollRowToVisible:i];
return;
}
}
}[/tt]
Maintenant il faut que j'apprenne à me servir des évènements pour que tout cela se passe à chaque frappe clavier dasn un nssearchfield... Merci encore
- (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)range
devait être efficace également.
--->
- (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)rang
--->
NSComparisonResult est un lien actif vers une énumération de constantes entières.
typedef enum _NSComparisonResult {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
} NSComparisonResult;
Le premier vaut -1, et les autres suivent NSOrderedSame=0 , NSOrderedDescending=1.
Mais bon, Apple peut à tout moment décider de changer ces valeurs, et puis garder les expressions littérales de ces constantes est à préférer.
On peut coder ainsi :
NSComparisonResult result=[ string1 compare:string2 options:NSLiteralSearch range:tonRange];
if(result==NSOrderedSame) // ils sont égaux
ou en plus concis
if([string1 compare:string2 options:NSLiteralSearch range:tonRange]==NSOrderedSame){
.......
}
Ma méthode de recherche est un IBAction
J'ai une variable Outlet pour chaque NSSearchField
Ma méthode est lié à chaque nssearchfield
J'ai rajouté un message d'alerte pour arrêter la frappe lorsque la chaine tapée est introuvable et ça marche !!! Pas besoin d'event, l'appli repère la frappe fait tourner la recherche à chaque caractère tapé, incroyable.... OUtlet et IBAction m'épate sur ce coup... Ou est-ce lié au NSSearchField ?
Juste une autre question de base : comment je fais pour que des nstextfield et nssearchfield soit en majuscule ou capitalized, actuellement je modifient la casse avant l'enregistrement dans la base mais je voudrais que lorsqu l'utilisateur tape un nom il apparaisse en majuscule, merci.
On attribue un NSFormatter
Data Formatting Programming Guide for Cocoa
Il faut donc en faire un perso et utiliser la méthode setFormatter de NSControl ou NSCell lors de awakeFromNib par exemple.
J'ai lu dans des forums, la doc d'Apple, project Omega... et dans NSFormatter, qu'il faut "overdriver", sans jamais comprendre de quoi il s'agit, généralement il me semble comprendre que c'est lié à des classes abstraites, qui sont pour moi assez... abstraites :P
D'ailleurs si j'ai bien compris ce sont des classes aux méthodes non implémentées... heu quelle utilité de ne pas implémenter des méthodes.. je ne saisi pas la logique...
Classes abstraites : Pour moi, cela veut dire qu'on ne peut utiliser que des sous-classes et la classe abstraite donne l'ensemble des méthodes communes, cela permet une unité dans un groupe de classes ... mais il faudrait repotasser cela dans les généralités sur Objective-C.
*
stringForObjectValue:
*
getObjectValue:forString:errorDescription:
*
attributedStringForObjectValue:withDefaultAttributes:[/tt]
Autant pour moi , override...
"override" veut dire " surcharger "...
C'est quand on redéfinit une méthode de la classe mère dans une classe fille
En Objective-C, c'est simple :P
En C++ il y a 3 ou 4 types de surcharges
Pour appeler le code de la classe mère à partir du code surchargé de la casse fille, on utilise [super nomDeLaMethode].
Par exemple il est fréquent de surcharger la méthode "dealloc", et d'appeler à la fin du code de surcharge la méthode "dealloc" de la classe mère avec [super dealloc].
Une classe abstraite c'est une classe pour laquelle toutes les méthodes ne sont pas implémentées. Il arrive parfois de parler de "surcharge d'une méthode abstraite" ce qui peut être un peu abusif comme langage, puisqu'on ne la surcharge pas vraiment, on l'implémente dans la classe fille alors qu'elle n'était pas implémentée.
L'intérêt de faire des classes abstraites c'est que ça permet de déclarer plusieurs méthodes communes à plusieurs objets : ensuite tu dérives cette classe abstraite en plusieurs sous-classes, qui elles vont implémenter les méthodes (et donc ne seront pas des classes abstraites, elles). Par contre on ne peut pas instancier une classe abstraite, puisque jsutement certaines de ses méthodes ne sont pas déclarées : on ne peut qu'instancier une de ses classes filles non abstraite.
exemple: une classe abstraite "Figure" qui déclare une méthode "getBoundingRect" (non implémentée) et est dérivée en des classes "Rectangle", "Square", "Circle", ... qui chacunes implémentent la méthode getBoundingRect, mais de façon différente
Ceci dit le terme "classe abstraite" est issu de la POO, mais en Objective-C c'est plutôt appelé des protocoles (cf "@protocol"
Par exemple le NSCopyingProtocol déclare la méthode "copyWithZone:" mais ne l'implémente pas. Ce ne sont que les classes filles, implémentant ce protocole, qui vont justement implémenter cette méthode en lui donnant du code, différent selon les classes filles.
L'intérêt c'est qu'ensuite du moment que tu sais qu'une classe implémente le protocole NSCopyingProtocol, tu n'as pas besoin de savoir de quelle classe il s'agit pour appeler la méthode copyWithZone. Tout comme du moment que tu sais que tu as une Figure, tu n'as pas besoin de savoir de quel type de figure il s'agit pour appeler getBoundingRect.