it-swarm.com.de

Erlaube nur Zahlen für die Eingabe von UITextField

Das iPad hat keine "Numpad" -Tastatur wie das iPhone/iPod.

Ich suche, wie ich die Tastatur des Benutzers so einschränken kann, dass er nur die Werte 0 bis 9 akzeptiert.

Ich würde mir vorstellen, UITextFields "shouldChangeCharactersInRange" zu verwenden, aber ich weiß nicht, wie man es am besten implementieren kann.

70
Demasterpl

So habe ich das Problem in einem SSN-Überprüfungsfeld behandelt. Sie können die maximale Länge ändern und die if-Anweisung entfernen, um den Tastaturtyp zu überprüfen.

Es gibt auch eine Logik zum Unterdrücken der Warnmeldungen für die maximale Länge, wenn der Benutzer eingibt, anstatt Daten einzufügen.

Im Kontext dieses Codes ist BasicAlert() ein #define-Makro, das einfach eine UIAlertView oder UIAlertController mit dem übergebenen Titel und den übergebenen Nachrichtenzeichenfolgen anzeigt.

// NOTE: This code assumes you have set the UITextField(s)'s delegate property to the object that will contain this code, because otherwise it would never be called.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    // allow backspace
    if (!string.length)
    {
        return YES;
    }

    // Prevent invalid character input, if keyboard is numberpad
    if (textField.keyboardType == UIKeyboardTypeNumberPad)
    {
        if ([string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet].invertedSet].location != NSNotFound)
        {
            // BasicAlert(@"", @"This field accepts only numeric entries.");
            return NO;
        }
    }

    // verify max length has not been exceeded
    NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string];

    if (proposedText.length > 4) // 4 was chosen for SSN verification
    {
        // suppress the max length message only when the user is typing
        // easy: pasted data has a length greater than 1; who copy/pastes one character?
        if (string.length > 1)
        {
            // BasicAlert(@"", @"This field accepts a maximum of 4 characters.");
        }

        return NO;
    }

    // only enable the OK/submit button if they have entered all numbers for the last four of their SSN (prevents early submissions/trips to authentication server)
    self.answerButton.enabled = (proposedText.length == 4);

    return YES;
}
68

Sie können diesen Code verwenden, um nur eine Zahl in textField zuzulassen.

Davor setzen Sie einen Delegaten für textField

      textFieldName.delegate=self;

oder

      [textFieldName setDelegate:self];

Verwenden Sie diesen Code, um nur Ziffern für textField zuzulassen

      - (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string {
//return yes or no after comparing the characters

      // allow backspace
      if (!string.length)
      {
           return YES;
      }

      ////for Decimal value start//////This code use use for allowing single decimal value
      //    if ([theTextField.text rangeOfString:@"."].location == NSNotFound)
      //    {
      //        if ([string isEqualToString:@"."]) {
      //            return YES;
      //        }
      //    }
      //    else
      //    {
      //        if ([[theTextField.text substringFromIndex:[theTextField.text rangeOfString:@"."].location] length]>2)   // this allow 2 digit after decimal 
      //        {
      //            return NO;
      //        }
      //    }
      ////for Decimal value End//////This code use use for allowing single decimal value

      // allow digit 0 to 9
      if ([string intValue])
      {
            return YES;
      }

      return NO;
    }
25
Aje

Sehr spezifische Schritte für den Swift-Code

Sie können eine Logik bereitstellen, die die Eingabe des Textfelds in der func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool-Methode einschränkt, indem Sie das UITextFieldDelegate-Protokoll implementieren.

Der Klarheit halber wird in diesen Schritten davon ausgegangen, dass Ihr Storyboard einView Controllermit einemTextfeld- Objekt enthält, das nur Ziffern akzeptieren soll.

  1. Erstellen Sie eine benutzerdefinierte Klasse für den Ansichtscontroller, die UIViewController erweitert. Stellen Sie sicher, dass die Szene in Ihrem Storyboard auf die benutzerdefinierte Klasse verweist, indem Sie den benutzerdefinierten Klassenwert in Xcode Identity Inspector festlegen.

    import UIKit
    class YourCustomController: UIViewController {
        override func viewDidLoad() {        
            super.viewDidLoad()
        }
    }
    
  2. Erstellen Sie einen Auslass aus dem Textfeld Ihrer Szene für Ihren benutzerdefinierten View Controller.

    class YourCustomController: UIViewController {
        @IBOutlet weak var numberField: UITextField!
        ...
    }
    
  3. Wenden Sie das UITextFieldDelegate-Protokoll in Ihrem benutzerdefinierten View-Controller an.

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
    }
    
  4. Weisen Sie in der viewDidLoad-Methode Ihres benutzerdefinierten Ansichtscontrollers den Delegaten Ihres Textfelds Ihrer benutzerdefinierten Ansichtscontrollerklasse zu.

    override func viewDidLoad() {        
        super.viewDidLoad()
        numberField.delegate = self
    }
    
  5. Fügen Sie die func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool-Methode der Variable UITextFieldDelegate hinzu. 

    Wenn Sie den benutzerdefinierten View-Controller im vorherigen Schritt als numberField-Delegat festlegen, wird diese Methode jedes Mal aufgerufen, wenn ein Benutzer ein Zeichen in das Textfeld eingibt. Wenn Ihre Methode true zurückgibt, bleibt das Zeichen im Textfeld. Wenn Ihre Methode false zurückgibt, bleibt das Zeichen nicht im Textfeld.

    Der Parameter string ist das Zeichen, das vom Benutzer eingegeben wird. Wenn das string-Zeichen in eine Int-Zeichen konvertiert werden kann, liegt es zwischen 0 und 9; Andernfalls handelt es sich um ein Zeichen ohne Nummer.

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
            return Int(string) != nil
        }
    }
    

(Siehe unten für den vollständigen Controller-Code.)


Beispiel View Controller mit Ziffernfeld nur

import UIKit

class YourCustomController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var numberField: UITextField!

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

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {        
        return Int(string) != nil
    }    
}

Beispiel View Controller mit einem dezimalen Textfeld

Wenn Sie eine Dezimalzahl unterstützen möchten, nutzen Sie NSNumberFormatter. Siehe die Codekommentare für die Unterschiede.

import UIKit

class YourCustomController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var numberField: UITextField!

    private var formatter: NSNumberFormatter!

    override func viewDidLoad() {        
        super.viewDidLoad()       
        numberField.delegate = self

        // Initialize the formatter; minimum value is set to zero; style is Decimal. 
        formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
        formatter.minimum = 0
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        // Combine the current text field value and the new string
        // character. If it conforms to the formatter's settings then
        // it is valid. If it doesn't then nil is returned and the
        // string character should not be allowed in the text field.         
        return formatter.numberFromString("\(textField.text)\(string)") != nil
    }    
}
17
whyceewhite

Versuchen Sie dies, um ein Textfeld-Löschproblem zu vermeiden 

Swift 3.0

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    guard NSCharacterSet(charactersInString: "0123456789").isSupersetOfSet(NSCharacterSet(charactersInString: string)) else {
        return false
    }
    return true
}

Swift 4.0

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
        return false
    }
    return true
}
15
SPatel
- (BOOL) textField: (UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string {

    NSNumberFormatter * nf = [[NSNumberFormatter alloc] init];
    [nf setNumberStyle:NSNumberFormatterNoStyle];

    NSString * newString = [NSString stringWithFormat:@"%@%@",textField.text,string];
    NSNumber * number = [nf numberFromString:newString];

    if (number)
        return YES;
    else
       return NO;
}
8
Adobels

Ich habe das angewendet und es funktioniert !!

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
// Check for non-numeric characters
NSUInteger lengthOfString = string.length;
for (NSInteger index = 0; index < lengthOfString; index++) {
    unichar character = [string characterAtIndex:index];
    if (character < 48) return NO; // 48 unichar for 0
    if (character > 57) return NO; // 57 unichar for 9
}
// Check total length for restrict user
NSUInteger proposedNewLength = textField.text.length - range.length + string.length;
if (proposedNewLength > 6)
    return YES;
return YES;                                                                                                                                     
}
6
iDev
Works fine for me :

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound) && !(range.length==1 && string.length==0)) {
            return NO;
        }
        return YES;
    }
2
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
    NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
    if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
        return NO;
    }
2
johnny

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

Wenn Sie mein Spezifikationsmuster verwenden, sieht der Code folgendermaßen aus

textField.delegate = self

lazy var specification: Specification = {
    return RegularExpressionSpecification(pattern: "^(|0|[1-9]\\d{0,6})$")
}()

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let textFieldString: NSString = textField.text ?? ""
    let s = textFieldString.stringByReplacingCharactersInRange(range, withString:string)
    return specification.isSatisfiedBy(s)
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let s = textField.text ?? ""
    let isTextValid = specification.isSatisfiedBy(s)
    if isTextValid {
        textField.resignFirstResponder()
    }
    return false
}
0
neoneye

Ich habe die Antwort von @ iDev so geändert, dass sie für Digitale und "." Funktioniert.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
     // Check for non-numeric characters
     NSUInteger lengthOfString = string.length;
     for (NSInteger index = 0; index < lengthOfString; index++) {
         unichar character = [string characterAtIndex:index];
         if ((character < 48) && (character != 46)) return NO; 
         // 48 unichar for 0, and 46 unichar for point
         if (character > 57) return NO; 
         // 57 unichar for 9
     }
     // Check for total length
     NSUInteger proposedNewLength = textField.text.length - range.length + string.length;
     if (proposedNewLength > 6)
         return YES;
     return YES; 
 }
0

Behalten Sie unterschiedliche Präsentationsdaten von der internen Darstellung. Es gibt einen einfacheren Weg. Lassen Sie NSNumberFormatter den Job erledigen:

 NSNumberFormatter* ns = [[NSNumberFormatter alloc] init];
 ns.numberStyle = NSNumberFormatterDecimalStyle;
 [ns setMaximumFractionDigits:2];
 // This is your internal representation of the localized number
 double a = [[ns numberFromString:self.textIVA.text] doubleValue]];

[mylabel setText:[NSString stringWithFormat:@"€ %@",
     [NSNumberFormatter localizedStringFromNumber:
                          [NSNumber numberWithDouble:a]
                                      numberStyle:NSNumberFormatterDecimalStyle]]];
0
giuseppe