J'ai un champ de texte avec la valeur par défaut de 0,00
Lorsque l'utilisateur appuie sur 1. Le champ de texte doit afficher 0,01
Lorsque l'utilisateur appuie sur 2. Le champ de texte doit afficher 0,12
Lorsque l'utilisateur appuie sur 3. Le champ de texte doit afficher 1,23
Lorsque l'utilisateur appuie sur 4. Le champ de texte doit afficher 12,34
Quelqu'un l'a-t-il fait avec SwiftUI?
3 Réponses :
L'idée est d'utiliser une sorte de proxy personnalisé pour formater le texte à la volée:
struct ContentView: View { @State var someNumber = 123 var body: some View { let formattedNumber = Binding<String>( get: { switch self.someNumber { case ..<0: return "???" case ..<10: return "0.0\(self.someNumber)" case ..<100: return "0.\(self.someNumber)" case 100...: return String(format: "%02f", Double(self.someNumber)/100) default: return "???" } }, set: { if let value = NumberFormatter().number(from: $0) { self.someNumber = value.intValue } } ) return TextField("Number", text: formattedNumber) } }
Avertissement : cette réponse contient des problèmes UX lorsque l'utilisateur tape, mais elle répond à la question d'origine
Recommandation : Pour ce type de champs de texte, je recommande d'utiliser un répondeur personnalisé qui répond aux événements de clavier et de texte au lieu de TextField
par défaut
votre recommandation est bien, mais pourquoi ne pas utiliser Textfield? TextField est le candidat parfait!
En raison du comportement par défaut du TextField
par défaut avec le curseur.
oui, je suis d'accord ... il existe encore une solution presque parfaite, veuillez voir ma propre interprétation :-)
essaye ça
import SwiftUI class Model: ObservableObject { @Published var txt = "" var value: Double { (Double(self.txt) ?? 0.0) / 100 } } struct ContentView: View { @ObservedObject var model = Model() var body: some View { let binding = Binding<String>(get: { () -> String in return String(format: "%.2f", self.model.value) }) { (s) in var s = s s.removeAll { (c) -> Bool in !c.isNumber } self.model.txt = s } return TextField("0.00", text: binding).keyboardType(.numbersAndPunctuation) .padding() .border(Color.red) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
voici le résultat
votre réponse fonctionne lorsque l'utilisateur entre la valeur la PREMIÈRE fois seulement. Allez essayer de modifier l'entrée une fois que le clavier est ignoré et que le comportement est totalement désactivé !?
aussi pour une raison quelconque dans une interface utilisateur complexe, il ne semble pas compiler. Dans un simple comme vous l'avez fourni, cela fonctionne moins le problème que je viens de commenter ci-dessus.
@ Learn2Code cela fonctionne tout le temps de la même manière, comme la première fois, quel problème avez-vous rencontré? je suis sur 11.4 (11E146)
@ Learn2Code et cela fonctionne également dans une "interface utilisateur plus complexe", toujours de la même manière.
si vous cliquez sur le champ de texte après avoir entré une valeur la première fois, les deux dernières valeurs restent toujours .00 et toute nouvelle entrée repousse simplement le reste du nombre mais il ne se remplit plus de droite à gauche.
@ Vidéo Learn2Code mise à jour :-), je ne vois pas ce problème.
Essayez d'ajouter un nombre très long, puis de le modifier à nouveau à partir de la plus droite.
@ Learn2Code je ne suis pas votre développeur, si vous avez un problème avec ma réponse, essayez de le faire à votre manière. Je ne supprime pas ma propre réponse juste parce que cela pourrait aider quelqu'un d'autre ... Cela fonctionne comme prévu, si vous aimez avoir 40 chiffres valides, n'utilisez pas Double comme stockage backend.
J'ai créé un currencyTextField qui s'enroule autour d'un UITextfield. Ce n'est pas de droite à gauche, mais vous pouvez le modifier en supprimant du code de curseur.
Voici la démo
et voici le repo https://github.com/youjinp/SwiftUIKit
on dirait que vous utilisez l'arabe ... si tel est le cas, sachez que cela fonctionne automatiquement par Apple si l'utilisateur a des paramètres de langue arabe (et / ou des paramètres de format)
Je ne suis pas ... J'en ai besoin pour remplir un champ de texte de devise, et de droite à gauche, c'est la manière standard de le faire.