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

j'ai un champ UITextField qui, lorsqu'il est cliqué, fait apparaître un bloc de nombres avec un point décimal en bas à gauche. J'essaie de limiter le champ pour qu'un utilisateur ne puisse placer qu'une décimale

p.ex.

2.5 OK

2..5 PAS OK

27
demandé sur lnafziger 2012-05-02 00:43:32

13 réponses

mettre en œuvre 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, donc s'il y a plus d'un point décimal, nous aurons au moins 3 éléments dans le tableau.

42
répondu lnafziger 2013-05-26 17:12:02

voici un exemple avec une expression régulière, l'exemple limite à seulement un point décimal et 2 décimales. Vous pouvez le personnaliser en fonction de 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;
}
13
répondu nizx 2015-03-09 14:58:10

pour Swift 2.3 pour empêcher l'utilisateur d'entrer le nombre décimal après deux places -

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
répondu pawan gupta 2017-02-04 07:41:41

S'appuyant sur la réponse acceptée, l'approche suivante valide trois cas qui sont utiles lorsqu'il s'agit de formats monétaires:

  1. une Très grande quantité
  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 réglé correctement, votre classe est conforme au protocole UITextField , et ajoutez ce qui suit délégué de la méthode.

- (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
répondu Kyle Clegg 2014-05-27 19:19:44

Swift 3 mettre en œuvre cette méthode UITextFieldDelegate pour empêcher l'utilisateur de taper un numéro 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 à la fois avec virgule ou point comme séparateur décimal. Vous pouvez également limiter le nombre de chiffres de fraction en utilisant ce modèle: "^[0-9]*((\.|,)[0-9]{0,2})?$" (dans ce cas 2).

3
répondu Miroslav Hrivik 2017-06-21 15:22:31
-(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
répondu jasveer 2012-09-13 05:20:40

essayez ceci: -

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
répondu Abhijeet Mallick 2016-09-06 14:38:27

Swift 3

Pas besoin de créer un tableau et vérifier le comte. L'utilisateur limite ne peut placer que 1 point décimal comme ceci.

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if (textField.text?.contains("."))! && string.contains(".")
    {
        return false
    }
    else
    {
        return true
    }
}
1
répondu RajeshKumar R 2017-03-27 07:55:13

dans n'importe quel objet auquel vous définissez le délégué de votre UITextField, ajoutez une méthode qui répond à " [- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string] " .

alors vous pouvez soit utiliser un objet NSNumberFormatter ou vous pouvez effectuer un contrôle de force brute pour une marque décimale déjà existante (en retournant NO si une marque décimale existe déjà).

0
répondu Michael Dautermann 2017-05-23 12:03:05

dit court, le format de nombre est comme suit [NSString stringWithFormat:@"%9.5f", x]; où 5 est le décimal après",".

0
répondu user2494999 2013-06-17 21:10:25

j'ai fait la solution, qui vous apporte le contrôle sur le nombre de décimales, de sorte que l'utilisateur peut taper seulement un séparateur décimal et vous pouvez également avoir un contrôle sur le nombre de décimales.

vient 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
répondu pedrouan 2014-05-30 06:55:45

Swift 4

la manière efficace et facile d'éviter les décimales multiples (. 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
répondu user3107831 2018-05-22 09:34:32

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
répondu Vivek 2018-08-21 13:23:15