2016-04-21 2 views
0

У меня есть текстовое поле, которое принимает только числовые значения. Мне было интересно, как я могу включить в себя возможность вводить сингл '.' для представления десятичной точки.shouldChangeCharactersInRange, который принимает одиночный '.'

У меня есть следующий код:

class ViewController: UIViewController, UITextFieldDelegate { 

    var formatter: NSNumberFormatter! 

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

    override func viewDidLoad() { 
     amountTextField.delegate = self 
     // Initialize the formatter; minimum value is set to zero; style is Decimal. 
     formatter = NSNumberFormatter() 
     formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle 
     formatter.minimum = 0 
    } 
} 

ответ

1

Вы должны использовать этот текст поле метода делегата:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // return NO to not change text 

     let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string) 

     if newString.characters.count > 0 { 

      let scanner: NSScanner = NSScanner(string:newString) 
      let isNumeric = scanner.scanDecimal(nil) && scanner.atEnd 

      return isNumeric 

     } else { 

      return true 
     } 
    } 
+0

Этот код имеет слишком много проблем, чтобы быть полезным. Он не работает со многими локалями. Он не работает, если пользователь перемещает каретку. Он не обрабатывает пользователя, который вырезает или вставляет текст. – rmaddy

+0

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

+0

@pableiros Спасибо! Как я могу изменить это, чтобы отображать только цифры, а не символ локали? –

0

Вы можете использовать целевой объект действие с .EditingChanged события вместо этого метода делегата, потому что это неудобно (не дает вам значения текста после смены) и не всегда работает (например, автокоррекция).

В обработчике .EditingChanged вы можете обрабатывать введенный текст с помощью регулярного выражения. При таком подходе вам придется сохранить значение старого текста.

Пример кода:

let decimalRegex = try! NSRegularExpression(pattern: "^[0-9]+(\\.[0-9]+)?$", options: []) 

func isValidText(text: String) -> Bool { 
    return text == "" || decimalRegex.numberOfMatchesInString(text, options: [], range: NSMakeRange(0, text.utf16.count)) != 0 
} 

textField.addTarget(self, action: #selector(self.textFieldTextChanged(_:)), forControlEvents: .EditingChanged) 
var oldText = "" 

func textFieldTextChanged(textField: UITextField) { 
    if isValidText(textField.text!) { 
     oldText = textField.text! 
    } else { 
     textField.text = oldText 
    } 
} 
+0

Использование регулярного выражения для проверки номера не является хорошей идеей. Он работает только с очень ограниченным набором локалей. Большая часть мира не использует период как десятичный разделитель, и на многих языках для чисел используются символы, отличные от 0-9. Ваш метод isValidText должен использовать 'NSNumberFormatter' для проверки введенного текста. – rmaddy

Смежные вопросы