Nur Geldbeträge im Textfeld zulassen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Nur Geldbeträge im Textfeld zulassen

    Hallo zusammen,

    ich habe ein Textfeld, in welches jemand Geldbeträge eingeben soll. Daher möchte ich gerne die mögliche Eingabe auf die Zahlen 0-9 und das Komma begrenzen.

    Hierzu hab ich folgenden Code geschrieben:


    Quellcode

    1. import UIKit
    2. class PaymentsMonthlyTVCell: UITableViewCell, UITextFieldDelegate {
    3. @IBOutlet weak var LabelPaymentsMonthly: UILabel!
    4. @IBOutlet weak var TextPaymentsMonthly: UITextField!
    5. override func awakeFromNib() {
    6. super.awakeFromNib()
    7. // Initialization code
    8. self.TextPaymentsMonthly.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 200/255, alpha: 1).cgColor
    9. self.TextPaymentsMonthly.layer.borderWidth = CGFloat(Float(1.0));
    10. }
    11. override func setSelected(_ selected: Bool, animated: Bool) {
    12. super.setSelected(selected, animated: animated)
    13. // Configure the view for the selected state
    14. }
    15. //MARK:- UITextFieldDelegate
    16. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    17. let allowedCharacters = ",1234567890"
    18. let allowedCharacterSet = CharacterSet (CharactersIn: allowedCharacters)
    19. let typedCharacterSet = CharacterSet(CharactersIn: String)
    20. return allowedCharacterSet.isSuperset(of: typedCharacterSet)
    21. }
    22. }
    Alles anzeigen
    Leider bekomme ich für die Zeilen 22 und 23 folgende Fehlermeldung:

    "Argument labels '(CharactersIn:)' do not match any available overloads"

    Kann jemand was damit anfangen?
    Ich verstehe auch nicht, warum er mir beim Schreiben des Codes in Zeile 22 nicht "CharactersIn:" vorschlägt.

    Hat jemand eine Idee woran das liegen könnte?

    Der Code befindet sich übrigens in der Swift Datei meiner TableViewCell, in welcher das Textfeld liegt.

    Danke für einen Hinweis.

    Gruß mac
  • Du solltest Dir überlegen, die Überprüfung z. B. mittels NSNumberFormatter zu machen ... Deine Überprüfung lässt fälschlicherweise Eingaben wie "123,0,34,1" zu.

    Die Methode zu Erstellen des CharacterSets heisst m. E. init(charactersIn: String), aber vielleicht erzähle ich da als nicht-Swifter auch Unsinn.. :D

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Definitiv solltest Du das mit (NS)NumberFormatter machen. Mit formatter.numberStyle = .currency hast Du dann gleich mehrere Fliegen auf einem Schlag erwischt. U.a. z.B. die Lokalisierung. Unser 1.234,56 und das englische 1,234.56 macht sonst später Probleme.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • @torquato

    ich habe deinen Rat befolgt, doch irgendwas scheint nicht ganz richtig zu sein. Er gibt mir auch bei Zahlen aus, daß es keine Zahl sei.
    Hast ne Idee, wo der Fehler liegt?

    Anbei der Code:

    Quellcode

    1. import UIKit
    2. class PaymentsMonthlyTVCell: UITableViewCell, UITextFieldDelegate {
    3. @IBOutlet weak var LabelPaymentsMonthly: UILabel!
    4. @IBOutlet weak var TextPaymentsMonthly: UITextField!
    5. override func awakeFromNib() {
    6. super.awakeFromNib()
    7. // Initialization code
    8. TextPaymentsMonthly.delegate = self
    9. self.TextPaymentsMonthly.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 200/255, alpha: 1).cgColor
    10. self.TextPaymentsMonthly.layer.borderWidth = CGFloat(Float(1.0));
    11. }
    12. override func setSelected(_ selected: Bool, animated: Bool) {
    13. super.setSelected(selected, animated: animated)
    14. // Configure the view for the selected state
    15. }
    16. // Methods or Functions
    17. func hideKeyboard() {
    18. TextPaymentsMonthly.resignFirstResponder()
    19. }
    20. func convertCurrencyToDouble(input: String) -> Double? {
    21. let numberFormatter = NumberFormatter()
    22. numberFormatter.numberStyle = .currency
    23. numberFormatter.locale = Locale.current
    24. return numberFormatter.number(from: input)?.doubleValue
    25. }
    26. func calculateAllTips() {
    27. guard let subtotal = convertCurrencyToDouble(input: TextPaymentsMonthly.text!) else {
    28. print("Not a number!: \(TextPaymentsMonthly.text!)")
    29. return
    30. }
    31. print("The subtotal is: \(subtotal)")
    32. }
    33. // Display will go back when clicking return
    34. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    35. TextPaymentsMonthly.resignFirstResponder()
    36. calculateAllTips()
    37. return true
    38. }
    39. }
    Alles anzeigen
  • Ich kenne mich mit solchen GUI-Sachen nicht besonders aus. Unter macOS kann man einem NSTextField einen Formatter als Property zuweisen, schon im Storyboard. Der kann dann vieles 'automagisch' übernehmen. Unter iOS scheint das so nicht zu gehen. Da muß man wohl mehr, selber von Hand, mit den Delegate-Methods machen. Mit iOS-GUI kenne ich mich noch weniger aus. Da hast Du inzwischen wahrscheinlich schon mehr Erfahrung als ich. ;) Da müßte ich selber auch erstmal googeln und mir das erarbeiten…

    Mal gucken, was die Experten dazu sagen.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Noch ein kleiner Tip, bzw. eine weitere Baustelle:

    Finanzbuchhaltung macht man nicht mit Fließkommazahlen (aka Double, Float, etc.), sondern mit ganzen Werten (soll heißen Int) der kleinsten Einheit (Cent, oder was auch immer). Fließkommazahlen haben 'Rundungsfehler', die sich aufaddieren.

    Probiere mal folgendes in einem Playground:

    Quellcode

    1. var sparschwein = 0.0
    2. for _ in 0..<1_000 {
    3. sparschwein += 0.3
    4. }
    5. sparschwein == 300.0 // false
    Du schmeißt 1.000-mal 30 Cent ins Sparschwein, und am Ende sind es trotzdem keine 300 EUR! WTF!? ;(

    Es gibt auch Währungen (Stichwort Lokalisierung), die gar keine Untereinheit habe, wie z.B. das JPY.

    Naja. Eine weitere Baustelle, die Du vielleicht beim weiteren Lernen zumindest im Hinterkopf behalten könntest… Nur gut gemeint. Ich erwähne das bei der Gelegenheit einfach mal.^^
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Deine Tipps sind super, vielen Dank!

    Ich hatte schon überlegt, ob es am Pfeil liegt, wenn ich auf Double verweise, aber den schreibe ich doch ganz einfach mit Bindestrich und kleiner als, oder gibt es da nen speziellen Shortcut?

    Dann werfe ich nochmal die Frage an die übrigen Leser in die Runde:

    Hat jemand eine Idee, warum mein Code nicht ganz richtig läuft und er immer denkt es sei keine Zahl???
  • Bertone105 schrieb:

    Hat jemand eine Idee, warum mein Code nicht ganz richtig läuft und er immer denkt es sei keine Zahl???
    Ja, hab ich.
    Zum einen lässt du ja laut deinem Code ganz oben nur die Zeichen ,1234567890 zur Eingabe zu. Den numberStyle des NumberFormatter stellst du auf .currency, was bedeutet, dass in dem String, der in eine Zahl umgewandelt werden soll, auch ein Währungssymbol erwartet wird. Das fehlt dann hier natürlich. Hier siehst du mal eine Übersicht mit Beispielen für NumberFormatter.

    Was du noch beachten musst ist, wenn du im Simulator testet, dass im Simulator auch das richtige Locale eingestellt ist. Das stellt man im Schema ein (Menü Product->Schema->Edit Schema... oder beim Klick auf den „Build and Run“ Button die Alt-Taste gedrückt halten).
  • Michael schrieb:

    Was du noch beachten musst ist, wenn du im Simulator testet, dass im Simulator auch das richtige Locale eingestellt ist. Das stellt man im Schema ein (Menü Product->Schema->Edit Schema... oder beim Klick auf den „Build and Run“ Button die Alt-Taste gedrückt halten).

    Ach, dies kannte ich noch gar nicht. Ich habe die Sprache/Region immer direkt im Simulator über die Einstellungen geändert. ;(
  • So, das Werk ist vollbracht. Als kleines Dankeschön anbei der fertige Code, falls Ihr auch mal was in Euro etc. eingeben müsst.
    Und man muß das Rad ja nicht zwei mal erfinden.

    Quellcode

    1. import UIKit
    2. class PaymentsMonthlyTVCell: UITableViewCell, UITextFieldDelegate {
    3. @IBOutlet weak var LabelPaymentsMonthly: UILabel!
    4. @IBOutlet weak var TextPaymentsMonthly: UITextField!
    5. var amt: Int = 0
    6. override func awakeFromNib() {
    7. super.awakeFromNib()
    8. // Initialization code
    9. TextPaymentsMonthly.delegate = self
    10. TextPaymentsMonthly.placeholder = updateAmount()
    11. self.TextPaymentsMonthly.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 200/255, alpha: 1).cgColor
    12. self.TextPaymentsMonthly.layer.borderWidth = CGFloat(Float(1.0));
    13. }
    14. override func setSelected(_ selected: Bool, animated: Bool) {
    15. super.setSelected(selected, animated: animated)
    16. // Configure the view for the selected state
    17. }
    18. // Methods or Functions
    19. func hideKeyboard() {
    20. TextPaymentsMonthly.resignFirstResponder()
    21. }
    22. func textField(_ _textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    23. if let digit = Int(string) {
    24. amt = amt * 10 + digit
    25. TextPaymentsMonthly.text = updateAmount()
    26. }
    27. if string == "" {
    28. amt = amt/10
    29. TextPaymentsMonthly.text = updateAmount()
    30. }
    31. return false
    32. }
    33. func updateAmount() -> String? {
    34. let formatter = NumberFormatter()
    35. formatter.numberStyle = NumberFormatter.Style.currency
    36. let amount = Double(amt/100) + Double(amt%100)/100
    37. return formatter.string(from: NSNumber(value: amount))
    38. }
    39. // Display will go back when clicking return
    40. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    41. TextPaymentsMonthly.resignFirstResponder()
    42. return true
    43. }
    44. }
    Alles anzeigen
  • Du hättest fairerweise erwähnen können, daß Dein jetzt vorgestelltes Ergebnis aus einem Top-5-Treffer einer Google-Suche stammt, die nach diesem Vlog-Eintrag verlinkt. o_O

    Bitte. Wer kürzt schon eine Property 'amount' zu amt ab und verwendet dann 'amount' trotzdem als lokale Variable? o_O Das fällt auf! :D
    Auch sonst bietet der Code noch viel Freiraum für den Rotstift. Mal sehen, ob ich am WE noch was dazu schreibe…

    Aber trotzdem: Schön, daß Du weitergekommen bist und Rückmeldung gibst.^^
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Hab ja nicht behauptet, daß der Code von mir ist:-) So weit bin ich noch nicht mit meinen Kenntnissen, finde aber, daß ich mit solchem Democode und eigenen Anpassungen mit der Zeit immer besser verstehe wie es geht. Nächstes Mal gerne mit Quellangabe und in ein paar Monaten dann auch mal ne komplette Eigenkreation.

    Also bisher hab ich noch keinen Fehler in der Funktionsweise entdeckt, bin aber gerne für einen Feinschliff offen torquato.

    Auch an euch Daumen hoch! Ist schön, wenn sich andere Zeit für einen nehmen und mit hilfreichen Tipps unterstützen.