Избегайте сбоев из двойного периода во время ограниченного набора символов

У меня есть проект калькулятора GPA, который я близок к совершенствованию. Мне нужно, чтобы пользователь не мог вводить число с плавающей запятой, несмотря на то, что ".0123456789" - единственные разрешенные символы. Например, если пользователь вводит 2.3. по какой-то причине моя программа падает, так как этот "ввод" не является плавающим. Я включил базу своего кода ниже.

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

    var allowed = CharacterSet.decimalDigits
    let period = CharacterSet.init(charactersIn: ".")
    allowed.formUnion(period)

    //UNCOMMENT when isSuperset is working
    //let characterSet = CharacterSet(charactersIn: string)
    //return allowed.isSuperset(of: characterSet)

    // Swift 3 appropriate solution
    let isSuperset = string.rangeOfCharacter(from: allowed.inverted) == nil
    return isSuperset
}


@IBAction func Calculate(_ sender: AnyObject) {

    // if not filled in
    if Credits1TF.text == "" || Grade1TF.text == "" || CumCredits.text == "" || CumGPA.text == "" || Credits1TF.text == "." || Grade1TF.text == "." || CumCredits.text == "." || CumGPA.text == "."
    {
 print...         
}            else 
        {
            //credits
            let credit1 = Float(Credits1TF.text!)!
            //grades
            let grade1 = Float(Grade1TF.text!)!
            //math
            let firstgrade = credit1 * grade1

Как бы я добавил добавление принятия только одной десятичной точки в текстовое поле наиболее практично, поскольку это относится к функции текстового поля? Или есть более простой / простой способ?

Обновление 1:

   let credit1 = Float(Credits1TF.text!)!
            if credit1 != nil
            {
                let newcredits1 = credit1

            //grades
            let grade1 = Float(Grade1TF.text!)!
                if grade1 != nil
                { let newgrade1 = grade1

Если я не говорю об этом неправильно, я получаю предупреждение о том, что "сравнение необязательного значения типа 'Float' с nil всегда возвращает true". У меня сложилось впечатление, что если credits1 или grade1!= Nil, мое числовое значение в порядке и не приведет к сбою в дальнейшем.

1 ответ

Решение
func textField(_ textField: UITextField, shouldChangeCharactersIn     range: NSRange, replacementString string: String) -> Bool {

    var allowed = CharacterSet.decimalDigits
    let period = CharacterSet.init(charactersIn: ".")
    allowed.formUnion(period)


    if (textField.text?.contains("."))! && string.contains(".")
    {
        return false
    }
    else
    {
        let isSuperset = string.rangeOfCharacter(from: allowed.inverted) == nil

        return isSuperset

    }

}

Этот код ограничивает допустимые символы до "0-9", а также позволяет вводить одну точку / десятичную точку. Возвращение символов 0-9 видно в остальной части оператора if. Этот ответ был вдохновлен ответом Радж в этом предыдущем вопросе Как я могу ограничить количество десятичных знаков в UITextField?,

Другие вопросы по тегам