[Résolu] UITextfield : Saisie d'un nombre décimal ou currency
Je suis en train de faire des recherches sur UITextfield et sur le moyen d'obliger l'utilisateur à saisir un nombre (décimal) ou une somme. Le tout dans l'unité monétaire et le format numérique (séparateur de millier, séparateur décimal etc).
Je ne suis pas le seul à m'être poser la question et j'étudie quelques pods trouvés ici ou là . J'ai aussi explorer les méthode délégué notamment :
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
Mes pistes :
- https://www.cocoacontrols.com/controls/tscurrencytextfield
- https://github.com/JoeFryer/JDFCurrencyTextField
- https://github.com/romaonthego/REFormattedNumberField
- http://www.globalnerdy.com/2015/01/03/how-to-program-an-ios-text-field-that-takes-only-numeric-input-with-a-maximum-length/
Je souhaiterais des conseils ainsi que votre retour d'expérience. Pour l'instant rien ne me plait vraiment : soit trop souple soit trop rigide (donc contraignant pour l'utilisateur)
De plus je souhaite connaà®tre la best practice, d'après vous : formater au fur et à mesure de la saisie. formater après la saisie d'un décimal, ne pas utiliser de uitexfield ?
D'avance merci de vos retours
Réponses
Merci de ta réponse
Je ne connaissais pas tu fais ça comment ?
Sinon tu gères comment le séparateur décimal, tu obliges le point comme séparateur, tu t'adaptes au préf de l'utilisateur ?
Que ce passe-t-il si l'utilisateur branche un clavier externe (comme c'est possible sur ipad) ?
S'il copie/colle depuis un autre textfield ?
Après mes réflexion j'ai pondu cela. Qui semble fonctionner. Qu'en pensez-vous ?
Je pense utiliser le type Set disponible dans Swift 1.2
Manque la gestion du symbole monétaire. Je le connais :
Mais j'aimerai être sûr qu'il est à la bonne place. Comment savoir s'il doit être devant ou derrière ?
Quitte à partir de NSMutableCharacterSet.decimalDigitCharacterSet() et appeler dessus addCharactersInString pour y ajouter le currencyDecimalSeparator et currencySymbol pour avoir le set complet.
Et après tu as des méthodes pour vérifier qu'une String ne contient que des caractères d'un NSCharacterSet donné.
Après, ce n'est pas aussi simple en pratique : (1) le currencySymbol doit se trouver à la bonne place (selon la NSLocale courante) et (2) le decimalSeparator ne doit être présent qu'une seule fois.
J'ai regardé NSCharacterSet mais franchement, vu que mon code est en swift et que dans la version 1.2 est prévu un type Set plus sexy. Je modifierais mon code avec un Set à ce moment là . (J'avais parler de Set sur le forum ici)
Set et NSCharacterSet ne sont pas du tout les mêmes classes.
- Le type Set de Swift 1.2 s'apparente à NSSet.
- Le type NSCharacterSet n'a pas d'équivalent en Swift.
NSCharacterSet offre des possibilités que NSSet / Set n'offrent pas. Comme par exemple :
- calculer le NSCharacterSet inverse d'un NSCharacterSet donné (pour trouver tous les caractères qui NE SONT PAS dans une liste de caractères)
- Utiliser les méthodes de String/NSString qui prennent un NSCharacterSet en paramètre, comme rangeOfCharacterFromSet: (et tester s'il est NSNotFound pour s'assurer qu'il n'y a aucun caractère non autorisé) ou stringByTrimmingCharactersInSet (qui peut servir pour enlever tous les caractères non autorisés d'une chaà®ne)
- Gérer l'Unicode (par exemple si tu autorises des caractères qui peuvent être représentés par plusieurs codepoints UniCode différents " comme c'est le cas de plusieurs caractères, comme les caractères accentués, mais aussi d'autres, pourquoi pas le symbole monétaire ou le point par exemple " alors NSCharacterSet saura gérer le cas et autoriser toutes les variantes.
etc
Petite évolution du code. J'y ai aussi inclu une variable qui manquait dans le code ci-dessous
Où l'on apprend que pour le Yen japonais il n'y a pas de chiffres après la virgule.
Reste la position du symbole monétaire à gérer
Voici le code que j'utilise pour déterminer quels boutons à activer :
Je ne accepte pas le currencySymbol en saisissant le texte, je le supprime en entrant dans le textField et je le rajoute en y sortant
Merci Ali,
Je tente de m'améliorer mais il se fait tard, j'ai viré quelques boucles for xd
Pour ceux que cela intéresse j'ai trouvé ça : Map, Filter and Reduce in Swift
En fonctionnel avec reduce :
Ou encore une autre solution, plutôt que d'utiliser un Set, utiliser un Range qui va du Character "0" au Character "9" (mais bon avec cette solution tu peux pas rajouter des éléments en dehors du range 0-9 comme le currencySymbol ou autre, donc ça limite l'usage dans ton cas, c'est plutôt juste pour la culture) :
J'en étais là :
Mais j'avoue tu va toujours plus loin, toujours plus haut, toujours plus fort !
C'est du 1.2 ton dernier code ?
Je me jette sur la beta des demain.
M'enfin pour moi
J'avoue je n'arrive pas trop à le lire (l'interpréter en langage humain de mon niveau)
Et puis surtout ce sont des fonctions qui existent dans tous les langages fonctionnels modernes (ruby, Swift,...) et qui sont vite incontournables donc c'est bon de les maà®triser.
Globalement je comprends ça ::)
C'est de mon niveau ^^
Mais alors ça ;D
Bon sinon ça serait pas plus simple de valider le contenu de la chaine avec une expression régulière (NSRegularExpression) ?
Surtout qu'on peut trouver tout un tas d'implémentation en swift (qui encapsulent NSRegularExpression), comme par exemple ici : https://gist.github.com/grosch/d3daeec1eefcf1614442
Voilà .
Je suis arrivé à cela
http://ilandes.github.io/RSDCurrencyTextFieldSampleCode/
Merci à tous
--
sujet lié : http://forum.cocoacafe.fr/topic/13519-résolu-effacement-du-symbole-monétaire-une-string-2-méthodes/