Подтвердить что ты не робот

Как ограничить число десятичных точек в UITextField?

У меня есть UITextField, который при нажатии вызывает цифровую панель с десятичной точкой в ​​левом нижнем углу. Я пытаюсь ограничить поле так, чтобы пользователь мог разместить только 1 десятичную метку

например.
2.5 OK
2..5 НЕ ОК

4b9b3361

Ответ 1

Реализовать метод shouldChangeCharactersInRange следующим образом:

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

Это создает массив строк, разбитых на десятичную точку, поэтому, если имеется более одной десятичной точки, у нас будет как минимум 3 элемента в массиве.

Ответ 2

Вот пример с регулярным выражением, пример ограничивает только одну десятичную точку и 2 десятичные числа. Вы можете настроить его в соответствии с вашими потребностями.

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

Ответ 3

Основываясь на принятом ответе, следующий подход проверяет три случая, которые полезны при работе с денежными форматами:

  • Чрезвычайно большие суммы
  • Более двух символов после десятичной точки
  • Более 1 десятичной точки

Убедитесь, что делегат текстового поля установлен правильно, ваш класс соответствует протоколу UITextField и добавляет следующий метод делегата.

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

Ответ 4

Для Swift 2.3, чтобы пользователь не вводил десятичное число после двух мест -

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

Ответ 5

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

Ответ 6

Попробуйте следующее: -

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
}

Ответ 7

Swift 3

Не нужно создавать массив и проверять количество. Ограниченный пользователь может разместить только 1 десятичную метку.

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

Ответ 8

Swift 3 Внедрите этот метод UITextFieldDelegate, чтобы пользователь не вводил неверный номер:

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
}

Он работает как с запятой, так и с точкой в ​​виде десятичного разделителя. Вы также можете ограничить количество цифр дроби, используя этот шаблон: "^[0-9]*((\\.|,)[0-9]{0,2})?$" (в данном случае 2).

Ответ 9

В любом объекте, в который вы установите делегат UITextField, добавьте метод, который отвечает на "[- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string]" .

Затем вы можете либо использовать объект NSNumberFormatter, либо выполнить проверку грубой силы для уже существующей метки десятичного знака (возврат NO, если десятичная метка уже существует).

Ответ 10

Кратко сказано, формат числа выглядит следующим образом [NSString stringWithFormat:@"%9.5f", x]; Где 5 - десятичное после ",".

Ответ 11

Я сделал решение, которое позволяет вам контролировать количество десятичных знаков, поэтому пользователь может набирать только один разделитель на десятичные знаки, и вы также можете контролировать количество десятичных знаков.

Просто установите значение decimalPlacesLimit правильно.

См. метод:

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