Comment forcer la saisie des caractères en majuscules dans une zone de texte sur l'iPhone ?
Réponses
Trop de publicités?Définir autocapitalizationType
à UITextAutocapitalizationTypeAllCharacters
sur le UITextField
.
Voir Protocole UITextInputTraits (adopté par UITextField) pour plus de détails.
Cette solution n'est pas entièrement satisfaisante.
Même avec le autocapitalizationType
réglé sur UITextAutocapitalizationTypeAllCharacters
l'utilisateur peut toujours appuyer sur la touche majuscule pour libérer le verrouillage des majuscules. Et le textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; return NO;
La solution n'est pas très bonne : nous perdons le point d'édition si l'utilisateur modifie le milieu du texte (après un textField.text =
le curseur d'édition va à la fin de la chaîne).
J'ai fait un mélange des deux solutions et voici ce que je propose : set UITextAutocapitalizationTypeAllCharacters
et ajoutez le code suivant au délégué de l'utilisateur de l'application UITextField
.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
// Check if the added string contains lowercase characters.
// If so, those characters are replaced by uppercase characters.
// But this has the effect of losing the editing point
// (only when trying to edit with lowercase characters),
// because the text of the UITextField is modified.
// That is why we only replace the text when this is really needed.
NSRange lowercaseCharRange;
lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];
if (lowercaseCharRange.location != NSNotFound) {
textField.text = [textField.text stringByReplacingCharactersInRange:range
withString:[string uppercaseString]];
return NO;
}
return YES;
}
Bien que toutes les autres réponses fonctionnent effectivement (elles mettent l'entrée en majuscules), elles ont toutes le problème que la position du curseur n'est pas conservée (essayez d'insérer un caractère au milieu du texte existant). Cela se produit apparemment dans le setter de UITextField
's text
et je n'ai pas trouvé de moyen de la restaurer par programme (par exemple, en rétablissant la propriété originale selectedTextRange
ne fonctionne pas).
Cependant, la bonne nouvelle, c'est qu'il existe un moyen direct de remplacer les pièces d'une UITextField
(ou UITextView
), qui ne souffre pas de ce problème :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// not so easy to get an UITextRange from an NSRange...
// thanks to Nicolas Bachschmidt (see http://stackoverflow.com/questions/9126709/create-uitextrange-from-nsrange)
UITextPosition *beginning = textField.beginningOfDocument;
UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
UITextPosition *end = [textField positionFromPosition:start offset:range.length];
UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end];
// replace the text in the range with the upper case version of the replacement string
[textField replaceRange:textRange withText:[string uppercaseString]];
// don't change the characters automatically
return NO;
}
Pour plus d'informations sur ces méthodes, voir la documentation de l'application UITextInput
.
Plutôt que de vérifier si le caractère est en majuscule ou en minuscule, il suffit de supposer qu'il s'agit d'une minuscule. C'est beaucoup plus simple.
Dans le
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
méthode :
NSString *newString = [[textField.text stringByAppendingString:string] uppercaseString];
textField.text = newString;
return NO;
Voici mon code, lorsque j'ai 6 textFields
J'espère que vous comprendrez ce que je veux dire.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField==self.textField6) {
self.textField6.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]];
return NO;
}
return YES;}