web-dev-qa-db-fra.com

Comment puis-je limiter le nombre de points décimaux dans un UITextField?

J'ai un UITextField qui, lorsqu'on clique dessus, fait apparaître un pavé numérique avec un point décimal en bas à gauche. J'essaie de limiter le champ de sorte qu'un utilisateur ne puisse placer qu'une marque décimale

par exemple.
2.5 OK
2..5 PAS OK

27
user1282180

Implémentez la méthode shouldChangeCharactersInRange comme ceci:

// Only allow one decimal point
// Example assumes ARC - Implement proper memory management if not using.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    NSArray  *arrayOfString = [newString componentsSeparatedByString:@"."];

    if ([arrayOfString count] > 2 ) 
        return NO;

    return YES;
}

Cela crée un tableau de chaînes divisées par le point décimal. Ainsi, s'il y a plus d'un point décimal, nous aurons au moins 3 éléments dans le tableau.

42
lnafziger

Voici un exemple avec une expression régulière, l'exemple se limitant à une décimale et à 2 décimales. Vous pouvez le modifier pour répondre à vos besoins.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    NSString *expression = @"^[0-9]*((\\.|,)[0-9]{0,2})?$";
    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:&error];
    NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString options:0 range:NSMakeRange(0, [newString length])];
    return numberOfMatches != 0;
}
14
nizx

Pour Swift 2.3, empêcher l'utilisateur de saisir un nombre décimal après deux positions -

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    let decimalPlacesLimit = 2
    let rangeDot = txtPrice.text!.rangeOfString(".", options: .CaseInsensitiveSearch)

    if rangeDot?.count > 0
    {
        if (string == ".")
        {
            print("textField already contains a separator")
            return false
        }
        else {

            var explodedString = txtPrice.text!.componentsSeparatedByString(".")
            let decimalPart = explodedString[1]
            if decimalPart.characters.count >= decimalPlacesLimit && !(string == "")
            {
                print("textField already contains \(decimalPlacesLimit) decimal places")
                return false
            }
        }
    }
}
6
pawan gupta

En s'appuyant sur la réponse acceptée, l'approche suivante valide trois cas utiles pour traiter les formats monétaires:

  1. Très grandes quantités
  2. Plus de 2 caractères après le point décimal
  3. Plus de 1 point décimal

Assurez-vous que le délégué de votre champ de texte est défini correctement, que votre classe est conforme au protocole UITextField et ajoutez la méthode de délégué suivante.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
  // Check for deletion of the $ sign
  if (range.location == 0 && [textField.text hasPrefix:@"$"])
    return NO;

  NSString *updatedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
  NSArray *stringsArray = [updatedText componentsSeparatedByString:@"."];

  // Check for an absurdly large amount
  if (stringsArray.count > 0)
  {
    NSString *dollarAmount = stringsArray[0];
    if (dollarAmount.length > 6)
      return NO;
  }

  // Check for more than 2 chars after the decimal point
  if (stringsArray.count > 1)
  {
    NSString *centAmount = stringsArray[1];
    if (centAmount.length > 2)
      return NO;
  }

  // Check for a second decimal point
  if (stringsArray.count > 2)
    return NO;

  return YES;
}
5
Kyle Clegg

Swift 3 Implémentez cette méthode UITextFieldDelegate pour empêcher l'utilisateur de saisir un nombre non valide:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let text = (textField.text ?? "") as NSString
    let newText = text.replacingCharacters(in: range, with: string)
    if let regex = try? NSRegularExpression(pattern: "^[0-9]*((\\.|,)[0-9]*)?$", options: .caseInsensitive) {
        return regex.numberOfMatches(in: newText, options: .reportProgress, range: NSRange(location: 0, length: (newText as NSString).length)) > 0
    }
    return false
}

Il fonctionne avec une virgule ou un point comme séparateur décimal. Vous pouvez également limiter le nombre de chiffres de fraction à l'aide de ce modèle: "^[0-9]*((\\.|,)[0-9]{0,2})?$" (dans ce cas, 2).

4
Miroslav Hrivik

Essaye ça :-

public func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {

    if(text == "," || text == "." ){
        let countdots = textView.text!.componentsSeparatedByString(".").count - 1

        if countdots > 0 && (text == "." || text == "," )
        {
            return false
        }
    }

    return true
}
2
Abhijeet Mallick
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    if(textField == min_textfield )
    {
        if([textField.text rangeOfString:@"."].location == NSNotFound)
        {
            if([string isEqualToString:@"."] )
            {
                flag_for_text = 1;
            }
            else 
            {
                textField.text = [NSMutableString stringWithFormat:@"%@",textField.text];
            }
        }
        else 
        {
            if([string isEqualToString:@"."])
            {
                return NO;
            }
            else 
            {
                textField.text = [NSMutableString stringWithFormat:@"%@",textField.text];
            }
        }
    }
}
2
jasveer

Swift 3  

Pas besoin de créer un tableau et de vérifier le nombre. L'utilisateur limité ne peut placer qu'une seule marque décimale de ce type. 

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if (textField.text?.contains("."))! && string.contains(".")
    {
        return false
    }
    else
    {
        return true
    }
}
1
RajeshKumar R

Swift 4

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

    // Allow to remove character (Backspace)
    if string == "" {
        return true
    }

   // Block multiple dot
    if (textField.text?.contains("."))! && string == "." {
        return false
    }

    // Check here decimal places
    if (textField.text?.contains("."))! {
        let limitDecimalPlace = 2
        let decimalPlace = textField.text?.components(separatedBy: ".").last
        if (decimalPlace?.count)! < limitDecimalPlace {
            return true
        }
        else {
            return false
        }
    }
    return true
}

Objectif c

//Create this variable in .h file or .m file
float _numberOfDecimal;

//assign value in viewDidLoad method
numberOfDecimal = 2;

#pragma mark - TextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    // Allow to remove character (Backspace)
    if ([string isEqualToString:@""]) {
        return true;
    }

    // Block multiple dot
    if ([textField.text containsString:@"."] && [string isEqualToString:@"."]) {
        return false;
    }

    // Check here decimal places
    if ([textField.text containsString:@"."]) {
        NSString *strDecimalPlace = [[textField.text componentsSeparatedByString:@"."] lastObject];

        if (strDecimalPlace.length < _numberOfDecimal) {
            return true;
        }
        else {
            return false;
        }
    }
    return true;
}
0
Vivek

Swift 4

le nombre maximal de nombres entiers est égal à 4, c'est-à-dire 9999, et le nombre maximal de chiffres décimaux est égal à 2. Le nombre maximal peut être égal à 9999,99.

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


    // 100 is the tag value of our textfield
    /*or you may use "if textfield == myTextField{" if you have an IBOutlet to that textfield */
    if textField.tag == 100 {

        //max length limit of text is 8
        if textField.text!.count > 8 && string != "" {
            return false
        }

        let maxLength = 8
        let currentString: NSString = textField.text! as NSString 

// Utiliser le code suivant Si vous saisissez price dans ce champ de texte et que vous souhaitez que $ soit automatiquement inséré au début lorsque l'utilisateur commence à taper dans ce champ de texte, vous pouvez également utiliser un autre caractère au lieu de $. Sinon, commentez les 3 lignes suivantes du code de condition if

        if currentString.length == 0 {
            priceTextField.text = "$"
        }

// nouvelle chaîne après insertion des nouveaux caractères entrés

        let newString: NSString =
            currentString.replacingCharacters(in: range, with: string) as NSString


        if newString.length > maxLength{
            return false
        }

        if (textField.text!.range(of: ".") != nil) {
            let numStr = newString.components(separatedBy: ".")
            if numStr.count>1{
                let decStr = numStr[1]
                if decStr.length > 2{
                    return false
                }
            }
        }

        var priceStr: String = newString as String

        if (textField.text!.range(of: "$") != nil) {
            priceStr = priceStr.replacingOccurrences(of: "$", with: "")
        }

        let price: Double = Double(priceStr) ?? 0

        if price > 9999.99{
            return false
        }

        switch string {
        case "0","1","2","3","4","5","6","7","8","9":
            return true
        case ".":
            let array = Array(textField.text!)
            var decimalCount = 0
            for character in array {
                if character == "." {
                    decimalCount = decimalCount + 1
                }
            }

            if decimalCount == 1 {
                return false
            } else {
                return true
            }
        default:

            let array = Array(string)
            if array.count == 0 {
                return true
            }
            return false
        }
    }
    return true
}
0
pravir

Dans l'objet que vous définissiez à votre délégué UITextField, ajoutez une méthode qui répond à "[- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string]" .

Ensuite, vous pouvez utiliser un objet NSNumberFormatter ou vous pouvez rechercher une marque de décimale déjà existante (en retournant NO si une marque décimale existe déjà).

0

En résumé, le format numérique est le suivant [NSString stringWithFormat:@"%9.5f", x]; où 5 est le nombre décimal après ",".

0
user2494999

Swift 4

Le moyen simple et efficace d’éviter plusieurs points décimaux (. Ou,) dans UITextField:

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if(string == "," || string == "." ){

        if ((textField.text?.contains(","))! || (textField.text?.contains("."))!){
            return false
        }
    }
    return true
}
0
user3107831

J'ai fait la solution, qui vous permet de contrôler le nombre de décimales, afin que l'utilisateur ne puisse taper qu'un seul séparateur décimal et vous pouvez également contrôler le nombre de décimales.

Il suffit de définir correctement la valeur decimalPlacesLimit .

Voir la méthode:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSLog(@"text on the way: %@", string);
    NSUInteger decimalPlacesLimit = 2;

    NSRange rangeDot = [textField.text rangeOfString:@"." options:NSCaseInsensitiveSearch];
    NSRange rangeComma = [textField.text rangeOfString:@"," options:NSCaseInsensitiveSearch];
    if (rangeDot.length > 0 || rangeComma.length > 0){
        if([string isEqualToString:@"."]) {
            NSLog(@"textField already contains a separator");
            return NO;
        } else {
            NSArray *explodedString = [textField.text componentsSeparatedByString:@"."];
            NSString *decimalPart = explodedString[1];
            if (decimalPart.length >= decimalPlacesLimit && ![string isEqualToString:@""]) {
                NSLog(@"textField already contains %d decimal places", decimalPlacesLimit);
                return NO;
            }
        }
    }

    return YES;
}
0
pedrouan