Сбой приложения из-за отсутствия значений в поле uiText

Когда я ввожу значение в UiTextField и нажимаю кнопку добавления, приложение работает отлично, но если я не ввожу значение в UiTextField, то нажимаю кнопку добавления, и все приложение вылетает. Может кто-то, пожалуйста, помогите мне и покажите мне свет. Спасибо заранее и добрые пожелания для вас и вашей семьи.

Это мой код

import UIKit

class ViewController: UIViewController,UITextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.textFild.delegate = self

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    @IBOutlet var textFild: UITextField!

    @IBAction func ButtonAwesome(sender: AnyObject) {



        let value:Double = Double(textFild.text!)!


        let sum:Double = value - 1;



        let alert = UIAlertController(title: "km", message:  "\(sum)", preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "Exit", style: UIAlertActionStyle.Default, handler: nil))
        self.presentViewController(alert,animated: true, completion: nil)



    }


    func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString stringer: String) -> Bool
    {

        if (textField.text == "" && (stringer == ".")) {
            return false;
        }


        let countdots = textField.text!.componentsSeparatedByString(".").count - 1

        if countdots > 0 && stringer == "."
        {
            return false
        }


        return true
    }




}

3 ответа

Более надежным решением было бы использовать оператор объединения nil, чтобы утверждать, что инициализация value никогда не подведет

@IBAction func ButtonAwesome(sender: AnyObject) {
    let value = Double(textFild.text ?? "0") ?? 0
    let sum:Double = value - 1;

    let alert = UIAlertController(title: "km", message:  "\(sum)", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Exit", style: UIAlertActionStyle.Default, handler: nil))
    self.presentViewController(alert,animated: true, completion: nil)
}

Это действительно для любого из следующих "неожиданных" значений textField.text: nil, "" (пустой) или какой-либо символ, который нельзя использовать для инициализации Double переменная типа (например, "a"). Для всех этих случаев value это дать значение 0,


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

Сначала мы рассмотрим опасность принудительного разворачивания дополнительных компонентов - не безопасного решения. Что, если textField.text содержит nil или нечисловой символ, например "a"? Результат:

var myTextFieldText : String? = nil

/* Example 1: nil value causes runtime error */
if myTextFieldText != "" { // this is 'true' -> enter if closure
    let value:Double = Double(myTextFieldText!)!
    /* this will fail at run time since we are forcibly (un-safely)
       unwrapping an optional containing 'nil'                           */
}

/* Example 2: non-numeric string character causes runtime error */
myTextFieldText = "a"
if myTextFieldText != "" { // this is 'true' -> enter if closure
    let value:Double = Double(myTextFieldText!)!
    /* this will fail at run time since we cannot initalize a
       Double with a string value "a", hence 'Double(myTextFieldText!)'
       returns nil, but since we've appended '!', we, like above,
       forcibly tries to unwrap this optional of value nil              */
}

Как правило, вы всегда должны использовать условное развертывание опций, чтобы избежать nil значение при принудительном распаковывании необязательных параметров, последнее приводит к ошибке времени выполнения.

Более надежная версия приведенного выше примера с использованием оператора объединения nil:

myTextFieldText = nil

let valueA = Double(myTextFieldText ?? "0") ?? 0 // 0
/* OK, Double(myTextFieldText ?? "0") = Double("0") = 0                  */

myTextFieldText = "a"
let valueB = Double(myTextFieldText ?? "0") ?? 0 // 0
/* OK, Double(myTextFieldText ?? "0") = Double("a") = nil (fails)
    => use rhs of outer '??' operator: nil ?? 0 = 0                      */

Для альтернативного метода, где вы расширяете UITextField чтобы охватить вашу строку для преобразования числовых типов, смотрите аккуратный ответ Leos в следующей теме:

В ветке также содержатся некоторые другие полезные сведения о чтении текста в виде числовых значений из UITextField экземпляров.


Наконец, при работе с преобразованием значений типа String в Double может оказаться целесообразным использовать фиксированное значение точности по числу десятичных цифр в полученном значении Double. Для подробного примера того, как это сделать, используя NSNumberFormatter и расширения см.:

Пожалуйста, замените метод buttonAwesome следующим кодом, где вы проверяете, не является ли текстовое поле пустым, это будет работать, если текстовое поле имеет значение:

@IBAction func ButtonAwesome(sender: AnyObject) {

    if textFild.text != "" {

    let value:Double = Double(textFild.text!)!


    let sum:Double = value - 1;


    let alert = UIAlertController(title: "km", message:  "\(sum)", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Exit", style: UIAlertActionStyle.Default, handler: nil))
    self.presentViewController(alert,animated: true, completion: nil)

    }

}

Поскольку textfield.text является необязательным значением, и, как в вашем случае, текстовое поле может или не может иметь текст. Так что вы должны проверить на необязательность, как указано ниже.

if let textIsAvailable = textfield.text
{
        print("Text \(textIsAvailable)")
}

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

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