wake-up-neo.com

Wie kann ich UITextField so einschränken, dass nur Zahlen in Swift verwendet werden?

Ich möchte, dass der Benutzer nur numerische Werte in eine UITextField eingibt. Auf dem iPhone können wir die numerische Tastatur anzeigen, auf dem iPad kann der Benutzer jedoch zu jeder Tastatur wechseln.

Gibt es eine Möglichkeit, den Benutzer einzuschränken, nur numerische Werte in einer UITextField einzugeben?

56
user5034941

Hier sind meine 2 Cents. (Nur auf Swift 2 getestet)

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

  let aSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
  let compSepByCharInSet = string.componentsSeparatedByCharactersInSet(aSet)
  let numberFiltered = compSepByCharInSet.joinWithSeparator("")
  return string == numberFiltered

}

Dies ist nur etwas strenger. Kein Dezimalpunkt.

Ich hoffe es hilft :) 

PS: Ich nahm an, Sie haben sich trotzdem um den Delegierten gekümmert.

Update: Swift 3.0 :

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
    let compSepByCharInSet = string.components(separatedBy: aSet)
    let numberFiltered = compSepByCharInSet.joined(separator: "")
    return string == numberFiltered
}
72
Mr H

Lösung für Swift 3.0 und höher

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
  {
    let allowedCharacters = CharacterSet.decimalDigits
    let characterSet = CharacterSet(charactersIn: string)
    return allowedCharacters.isSuperset(of: characterSet)
  }
59
Hiren Panchal

Swift 2.0

Um nur Zahlen und ein "." dezimal in uitextfield.

func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString string: String) -> Bool
{
    let newCharacters = NSCharacterSet(charactersInString: string)
    let boolIsNumber = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
    if boolIsNumber == true {
        return true
    } else {
        if string == "." {
            let countdots = textField.text!.componentsSeparatedByString(".").count - 1
            if countdots == 0 {
                return true
            } else {
                if countdots > 0 && string == "." {
                    return false
                } else {
                    return true
                }
            }
        } else {
            return false
        }
    }
}
11
Cian

In Swift 4.1 und Xcode 9.4.1

Fügen Sie Ihrer Klasse UITextFieldDelegate hinzu

class YourViewController: UIViewController, UITextFieldDelegate

Dann schreibe diesen Code in deine viewDidLoad ()

mobileNoTF.delegate = self

Schreiben Sie diese Textfeld-Delegatfunktion

//MARK - UITextField Delegates
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    //For mobile numer validation
    if textField == mobileNoTF {
        let allowedCharacters = CharacterSet(charactersIn:"+0123456789 ")//Here change this characters based on your requirement
        let characterSet = CharacterSet(charactersIn: string)
        return allowedCharacters.isSuperset(of: characterSet)
    }
    return true
}
11
iOS

Akzeptieren Sie Dezimalwerte in Textfeldern mit einem Punkt (.) In Swift 3

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted

    let components = string.components(separatedBy: inverseSet)

    let filtered = components.joined(separator: "")

    if filtered == string {
        return true
    } else {
        if string == "." {
            let countdots = textField.text!.components(separatedBy:".").count - 1
            if countdots == 0 {
                return true
            }else{
                if countdots > 0 && string == "." {
                    return false
                } else {
                    return true
                }
            }
        }else{
            return false
        }
    }
}
8
Raj Joshi
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    // return true if the replacementString only contains numeric characters
    let digits = NSCharacterSet.decimalDigitCharacterSet()
    for c in string {
        if !digits.characterIsMember(c) {
            return false
        }
    }

    return true
}

Diese Lösung funktioniert auch, wenn der Benutzer die Tastatur wechselt oder versucht, eine nicht numerische Zeichenfolge in das Textfeld einzufügen.

Stellen Sie sicher, dass Sie die delegate-Eigenschaft des entsprechenden Textfelds festlegen.

6
ndmeiri

Nur IPhone-Lösung

In welchem ​​UITextField Sie diese Werte erhalten, können Sie die Art der Tastatur angeben, die angezeigt werden soll, wenn jemand das Textfeld berührt.

Z.B. eine nur numerische Tastatur.

Wie dieser Screenshot:

 enter image description here

Ipad

Das iPad unterstützt die numerische Tastatur nicht. Daher haben Sie die Wahl, entweder das iPad nicht zu unterstützen, das Feld nach dem Senden zu bestätigen oder einem der anderen Vorschläge zu folgen, um ein vernünftiges Verhalten bei der Ausführung auf einem iPad zu erstellen.

6

Hier ist eine einfache Lösung. Sie müssen das Ereignis "Änderung geändert" mit dieser Methode in Ihrem Controller verbinden

Swift 4

@IBAction func valueChanged(_ sender: UITextField) {
    if let last = sender.text?.last {
        let zero: Character = "0"
        let num: Int = Int(UnicodeScalar(String(last))!.value - UnicodeScalar(String(zero))!.value)
        if (num < 0 || num > 9) {
            //remove the last character as it is invalid
            sender.text?.removeLast()
        }
    }
}
3
shbli

Verwenden Sie Zahlenformatierer

Swift 4.x  

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
      let s = NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string)
      guard !s.isEmpty else { return true }
      let numberFormatter = NumberFormatter()
      numberFormatter.numberStyle = .none
      return numberFormatter.number(from: s)?.intValue != nil
 }
3
SPatel

Während die meisten dieser Lösungen funktionieren, ist zu beachten, dass Dezimalstellen in einigen Lokalisierungen durch ein "," und kein "." Getrennt werden.

Der sauberere Weg, dies zu tun, wäre

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let decimalCharacter = NSNumberFormatter().decimalSeparator
    let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
    characterSet.addCharactersInString(decimalCharacter)

    return replacementString.rangeOfCharacterFromSet(characterSet.invertedSet) == nil
}
2
AlexLittlejohn

Getestet in Swift 3.0

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool

{         
    let numberOnly = NSCharacterSet.init(charactersIn: "0123456789")
    let stringFromTextField = NSCharacterSet.init(charactersIn: string)
    let strValid = numberOnly.isSuperset(of: stringFromTextField as CharacterSet)

     return strValid
 }
2
iosLearner

Zunächst müssen Sie die UITextFieldDelegate-Klasse mit Ihrem eigenen .__ erben. Klasse

class ViewController: UIViewController, UITextFieldDelegate {

2. Fügen Sie ein IBOutlet hinzu

@IBOutlet weak var firstName: UITextField!

3. Sie müssen sicherstellen, dass dieses Objekt verwendet wird

override func viewDidLoad() {
        super.viewDidLoad()
   firstName.delegate = self
}


func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if textField == firstName {
                let allowedCharacters = "1234567890"
                let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
                let typedCharacterSet = CharacterSet(charactersIn: string)
                let alphabet = allowedCharacterSet.isSuperset(of: typedCharacterSet)
                return alphabet


      }
  }
2
akbar khan

Ich hatte das tatsächlich gemacht, als ich das Big Nerd Ranch-Buch durchgearbeitet hatte. Meine Lösung ist:

func textField(textField: UITextField, 
    shouldChangeCharactersInRange range: NSRange, 
    replacementString string: String) -> Bool {

    let newCharacters = NSCharacterSet(charactersInString: string)
    return NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
}

dies erlaubt nur die Zahlen 0-9, das "." ist auch komplizierter, da Sie nur ein "."

2
sgib
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if let numRange = string.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet()) {
        return false
    } else {
        return true
    }
   }
2
likarson

Erweitern Sie Ihren View Controller wie folgt:

class MyViewController: UIViewController, UITextFieldDelegate

In der Funktion viewDidLoad erweitern Sie Ihr Textfeld folgendermaßen:

myTextField.delegate = self

Und dann die folgende Funktion verwenden:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let isNumber = CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: string))
    let withDecimal = (
        string == NumberFormatter().decimalSeparator &&
        textField.text?.contains(string) == false
    )
    return isNumber || withDecimal
}

Dadurch wird sichergestellt, dass der Benutzer nur Dezimalstellen eingeben kann.

Swift 4 + Akzeptiert nur Number Und akzeptiert ein Trennzeichen

2
Aftab Ahmed

Um nur Zahlen und nur einen Dezimaloperator zuzulassen, können Sie diese Lösung verwenden:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let isNumber = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(NSCharacterSet(charactersInString: string))

    return isNumber || (string == NSNumberFormatter().decimalSeparator && textField.text?.containsString(string) == false)
}
2
hprione

Für einige Charaktere zulassen

func CheckAddress(string:String) -> Bool  {
        let numberOnly = NSCharacterSet.init(charactersIn: "[email protected],&#/")
        let stringFromTextField = NSCharacterSet.init(charactersIn: string)
        return numberOnly.isSuperset(of: stringFromTextField as CharacterSet)
    }

print("\(CheckAddress(string: "123"))") //True
print("\(CheckAddress(string: "asdf-"))") //True
print("\(CheckAddress(string: "asd123$"))") //false
1
Ilesh
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool

        {
            let textString = (textField.text! as NSString).replacingCharacters(in: range, with: string)

            if textField == self.phoneTextField  && string.characters.count > 0{
                let numberOnly = NSCharacterSet.decimalDigits
                let strValid = numberOnly.contains(UnicodeScalar.init(string)!)
                return strValid && textString.characters.count <= 10
            }
            return true
        }

im obigen Code funktioniert Swift 3 
NSCharacterSet .decimalDigits
Sie verwenden auch nur Buchstaben 
NSCharacterSet .Buchstaben
und Großbuchstaben, Kleinschreibung und alphanumerische Zeichen, Leerzeichen werden mit demselben Code .__ verwendet. oder siehe den Link

1

Ich habe die Version von Raj Joshi bearbeitet, um einen Punkt oder ein Komma zu erlauben:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let inverseSet = CharacterSet(charactersIn:"0123456789").inverted
    let components = string.components(separatedBy: inverseSet)
    let filtered = components.joined(separator: "")

    if filtered == string {
        return true
    } else {
        if string == "." || string == "," {
            let countDots = textField.text!.components(separatedBy:".").count - 1
            let countCommas = textField.text!.components(separatedBy:",").count - 1

            if countDots == 0 && countCommas == 0 {
                return true
            } else {
                return false
            }
        } else  {
            return false
        }
    }
}
1
Matthijs

Als ob es nicht genug Antworten gibt, hier meine. Ich denke, dass jedes Beispiel, das für Dezimaltrennzeichen zulässig ist, entweder in der Lokalisierung, in den Backspaces oder im Kopieren/Einfügen fehlerhaft ist.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if string.isEmpty {return true} //allow for backspace

    let decimalSeparator = NSNumberFormatter().decimalSeparator ?? "."
    let validChars = NSMutableCharacterSet(charactersInString: decimalSeparator)
    validChars.formUnionWithCharacterSet(NSCharacterSet.decimalDigitCharacterSet())

    if validChars.isSupersetOfSet(NSCharacterSet(charactersInString: string)){
        switch string.componentsSeparatedByString(decimalSeparator).count-1 {
        case 0: //no decimals
            return true

        case 1: //if adding decimal, only allow if no existing decimal
            if let existingText = textField.text{
                return existingText.componentsSeparatedByString(decimalSeparator).count <= 1
            }
            else {return true}

        default: //invalid decimals
            return false
        }
    }

    return false
}
1
David

Das Folgende ist der Code, den ich in Swift 3.0 verwendet habe, angepasst an den Code von Herrn H. Unterschiede sind, weil:

a) Die Deklaration der Delegiertenfunktion wurde in Swift 3.0 geändert. Neue Erklärung hier

b) Die NSCharacterSet-Deklaration wurde geändert.

func textField(_ shouldChangeCharactersIntextField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{

        let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted

        let components = string.components(separatedBy: inverseSet)

        let filtered = components.joined(separator: "")

        return string == filtered

}
1
ChinLoong

Ich denke, Sie können das Ändern des Tastaturtyps erzwingen, indem Sie das UITextInputTraits-Protokoll (optionaler Tastaturtyp) verwenden

//class ViewController: UIViewController, UITextInputTraits {

@IBOutlet weak var textFieldKeyboardType: UITextField!{
    didSet{
        textFieldKeyboardType.keyboardType = UIKeyboardType.NumberPad
    }
}
var keyboardType: UIKeyboardType { 
    get{ 
        return textFieldKeyboardType.keyboardType
    } 
    set{ 
        if newValue != UIKeyboardType.NumberPad{
            self.keyboardType = UIKeyboardType.NumberPad
        }
    } 
}
1
Lukas

Eine unkomplizierte Lösung für Double-Nummern (bedenken Sie, dass dies nicht die beste benutzerfreundliche Lösung ist) in Ihrem UITextFieldDelegate-Delegierten:

func textField(_ textField: UITextField,
               shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool {
        guard let currentString = textField.text as NSString? else {
            return false
        }
        let newString = currentString.replacingCharacters(in: range, with: string)
        return Double(newString) != nil
}
0
Tomasz Wójcik
Swift 2.0

func textField(textField: UITextField,
    shouldChangeCharactersInRange range: NSRange,
    replacementString string: String) -> Bool {

        let inverseSet = NSCharacterSet(charactersInString:"0123456789").invertedSet

        let components = string.componentsSeparatedByCharactersInSet(inverseSet)

        let filtered = components.joinWithSeparator("")

        return string == filtered

  }
0
tymac

Dies ist eine besser lesbare Version, die "0-9" plus "."

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    let existingTextHasDecimal = textField.text?.rangeOfString(".")
    let replacementTextHasDecimal = string.rangeOfString(".")
    let replacementTextAllCharacters = NSCharacterSet(charactersInString: string)
    let replacementTextOnlyDigits = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(replacementTextAllCharacters)

    if replacementTextHasDecimal != nil && existingTextHasDecimal != nil {
        return false
    }else{
        if replacementTextOnlyDigits == true {
            return true
        }else if replacementTextHasDecimal != nil{
            return true
        }else{
            return false
        }
    }
}
0
Enraged
func isValidNumber(str:String) -> Bool{
    if str.isEmpty {
        return false
    }
    let newChar = NSCharacterSet(charactersInString: str)
    let boolValid = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newChar)
    if boolValid{
        return true
    }else{
        let lst = str.componentsSeparatedByString(".")
        let newStr = lst.joinWithSeparator("")
        let currentChar = NSCharacterSet(charactersInString: newStr)
        if lst.count == 2 && !lst.contains("") && NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(currentChar){
            return true
        }
        return false
    }
}

Setzen Sie diese Funktion in Ihre "Senden" - oder "Speichern" -Methode, falls vorhanden.

0
den330

Swift 3 

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if textField==yourTextFieldOutlet {
                if(CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: yourTextFieldOutlet.text!))){
//if numbers only, then your code here
                }
                else{
                showAlert(title: "Error",message: "Enter Number only",type: "failure")
                }
            }
    return true
    }
0
ArgaPK

Sie können diesen Code verwenden, wenn Sie Dezimaltrennzeichen und/oder negative Zahlen zulassen möchten. Dieser Code ermöglicht jedoch ein Beispiel: "34." (Dezimaltrennzeichen am Ende), während der Text geändert wird. Sie müssen also einige Codebeispiele hinzufügen: textFieldShouldReturn- oder textFieldShouldEndEditing-Delegatfunktionen.

Der Code wurde in Swift 4 geschrieben, aber ich vermute, dass dies mit Swift 3 kompatibel ist.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else {
        return true
    }

    let replaced = (text as NSString).replacingCharacters(in: range, with: string)
    let decimalSeparator = NSLocale.current.decimalSeparator ?? ""

    // When user wants to delete las character
    if replaced == "" || replaced == "-" || replaced == "-0" {
        textField.text = "0"
        return false
    }

    // When text contains 0 before replace except "0."
    if replaced != "0" + decimalSeparator && replaced.hasPrefix("0") && text.underestimatedCount == 1 {
        textField.text = replaced.substring(from: replaced.index(after: replaced.startIndex))
        return false
    }

    // When user wants to delete minus sign
    if text.hasPrefix("-") && text.substring(from: text.index(after: text.startIndex)) == replaced {
        return false
    }

    // When user wants to delete before decimal separator
    if replaced.hasPrefix(decimalSeparator) || replaced.hasPrefix("-" + decimalSeparator) {
        return false
    }

    // When user wants to add zero the beginning of number... but allowing "0." or "-0." numbers
    let testReplaced = replaced.hasPrefix("-") ? replaced.substring(from: replaced.index(after: replaced.startIndex)) : replaced
    if testReplaced.count >= 2 && testReplaced.hasPrefix("0") && !testReplaced.hasPrefix("0" + decimalSeparator) {
        return false
    }

    // Every other cases
    let allowDecimal = self.allowFloat ? (decimalSeparator == "." ? "\\.?" : decimalSeparator + "?") : ""
    let allowSign = self.allowSigned ? "-?" : ""
    let pattern = "\(allowSign)[0-9]+\(allowDecimal)([0-9]+)?"

    do {
        let regexRange = (replaced as NSString).range(of: replaced)
        let regex = try NSRegularExpression(pattern: pattern, options: [])
        let matches = regex.matches(in: replaced, options: [], range: regexRange)
        return matches.count == 1 && matches.first!.range == regexRange
    }
    catch {}

    return false
}

Wenn Sie keine Dezimal- oder Negativzahlen zulassen möchten, müssen Sie die Tow-Variable durch die nächste Zeile ersetzen

let allowDecimal = ""
let allowSign = ""
0
Ferenc Kiss

Sie können shouldChangeCharactersInRange zusammen mit der Erweiterungsmethode String verwenden, um zu prüfen, ob die Eingabezeichenfolge eine Zahl ist oder nicht. 

extension String  {

    var isNumber : Bool {
        get{
            return !self.isEmpty && self.stringWithoutWhitespaces.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
        }
    }

    var stringWithoutWhitespaces: String {
        return self.replacingOccurrences(of: " ", with: "")
    }

}

//Mark: shouldChangeCharactersInRange
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    // return true if the string only contains numeric characters
    let isValid = string.stringWithoutWhitespaces.isNumber 
    return valid
}
0
Suhit Patil

Hier ist eine sauberere Lösung: 

 guard CharacterSet(charactersIn: "123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
     return false
 }
 return true

Für Dezimalzahlen einfach . eingeben, Beispiel 123456789.

0
Farhad