86 votes

N'autoriser que les nombres pour les champs UITextField

L'iPad n'a pas de clavier "Numpad" comme l'iPhone/iPod.

Je cherche à savoir comment restreindre le clavier de l'utilisateur pour qu'il n'accepte que les valeurs de 0 à 9.

J'imaginerais utiliser le champ UITextField "shouldChangeCharactersInRange" mais je ne connais pas la meilleure façon de l'implémenter.

88voto

Thuggish Nuggets Points 1337

Voici comment vous pourriez traiter le problème pour un champ de vérification du SSN : vous pouvez modifier la longueur maximale et supprimer le champ de vérification du SSN. if la vérification du type de clavier si nécessaire.

Il existe également une logique permettant de supprimer les alertes relatives à la longueur maximale lorsque l'utilisateur saisit des données au lieu de les coller.

Dans le cadre de ce code, presentAlert()/presentAlert: est juste une fonction de base qui présente un UIAlertController (ou un héritage UIAlertView ) en utilisant la chaîne de messages transmise.

Swift 5

// 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.
//
// There are also some better stylistic approaches in Swift to avoid all the 
// nested statements, but I wanted to keep the styles similar to allow others 
// to contrast and compare between the two languages a little easier.

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

    // Handle backspace/delete
    guard !string.isEmpty else {

        // Backspace detected, allow text change, no need to process the text any further
        return true
    }

    // Input Validation
    // Prevent invalid character input, if keyboard is numberpad
    if textField.keyboardType == .numberPad {

        // Check for invalid input characters
        if CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) {

            // Present alert so the user knows what went wrong
            presentAlert("This field accepts only numeric entries.")

            // Invalid characters detected, disallow text change
            return false
        }
    }

    // Length Processing
    // Need to convert the NSRange to a Swift-appropriate type
    if let text = textField.text, let range = Range(range, in: text) {

        let proposedText = text.replacingCharacters(in: range, with: string)

        // Check proposed text length does not exceed max character count
        guard proposedText.count <= maxCharacters else {

            // Present alert if pasting text
            // easy: pasted data has a length greater than 1; who copy/pastes one character?
            if string.count > 1 {

                // Pasting text, present alert so the user knows what went wrong
                presentAlert("Paste failed: Maximum character count exceeded.")
            }

            // Character count exceeded, disallow text change
            return false
        }

        // 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, etc)
        answerButton.isEnabled = (proposedText.count == 4)
    }

    // Allow text change
    return true
}

Objectif-C

// 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
{
    // Handle backspace/delete
    if (!string.length)
    {
        // Backspace detected, allow text change, no need to process the text any further
        return YES;
    }

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

    // Length Validation
    NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string];

    // Check proposed text length does not exceed max character count
    if (proposedText.length > maxCharacters)
    {
        // Present alert if pasting text
        // easy: pasted data has a length greater than 1; who copy/pastes one character?
        if (string.length > 1)
        {
            // Pasting text, present alert so the user knows what went wrong
            [self presentAlert: @"Paste failed: Maximum character count exceeded."];
        }

        // Character count exceeded, disallow text change
        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, etc)
    self.answerButton.enabled = (proposedText.length == maxCharacters);

    // Allow text change
    return YES;
}

29voto

Aje Points 91

Vous pouvez utiliser ce code pour n'autoriser que les nombres dans le champ textField.

Avant cela, définir un délégué pour textField

      textFieldName.delegate=self;

ou

      [textFieldName setDelegate:self];

Utilisez ensuite le code suivant pour n'autoriser que les chiffres dans le champ textField

      - (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;
    }

25voto

SPatel Points 1032

Essayez ceci pour éviter le problème d'effacement du champ de texte

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
}

19voto

whyceewhite Points 217

Des étapes très spécifiques pour le code Swift

Vous pouvez fournir une logique qui limite la saisie du champ de texte dans la fonction func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool en mettant en œuvre la méthode UITextFieldDelegate protocole.

Par souci de clarté, ces étapes partent du principe que votre storyboard contient un Contrôleur de vue avec un champ de texte qui ne doit accepter que des chiffres.

  1. Créez une classe personnalisée pour le contrôleur de vue qui étend la classe UIViewController . Assurez-vous que que la scène de votre storyboard se réfère à la classe personnalisée en définissant la valeur de la classe personnalisée dans l'inspecteur d'identité de Xcode.

    import UIKit
    class YourCustomController: UIViewController {
        override func viewDidLoad() {        
            super.viewDidLoad()
        }
    }
  2. Créez une sortie du champ de texte de votre scène vers votre contrôleur de vue personnalisé.

    class YourCustomController: UIViewController {
        @IBOutlet weak var numberField: UITextField!
        ...
    }
  3. Appliquer le UITextFieldDelegate dans votre contrôleur de vue personnalisé.

    class YourCustomController: UIViewController, UITextFieldDelegate {
        ...
    }
  4. Dans la section viewDidLoad assignez le délégué de votre champ de texte à votre classe de contrôleur de vue personnalisé.

    override func viewDidLoad() {        
        super.viewDidLoad()
        numberField.delegate = self
    }
  5. Ajouter le UITextFieldDelegate 's func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool méthode.

    En faisant de votre contrôleur de vue personnalisé le contrôleur de vue numberField dans l'étape précédente, cette méthode sera appelée chaque fois qu'un utilisateur saisira un caractère dans le champ de texte. Si votre méthode renvoie true le caractère restera dans le champ de texte. Si votre méthode renvoie false alors le personnage pas restent dans le champ de texte.

    Les string est le caractère saisi par l'utilisateur. Si le paramètre string peut être converti en un caractère Int il est compris entre 0 et 9 ; sinon, il s'agit d'un caractère non numérique.

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

(Voir ci-dessous le code complet du contrôleur de vue).


Exemple de contrôleur de vue avec un champ de texte à chiffres uniquement

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
    }    
}

Exemple de contrôleur de vue avec un champ de texte décimal

Si vous souhaitez prendre en charge un nombre décimal, tirez parti de l'option NSNumberFormatter . Voir les commentaires du code pour les différences.

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
    }    
}

9voto

siiiiiix Points 89
- (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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X