Присвоение значения текстового поля переменной в Swift

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

Я просто хочу сохранить значение ввода пользователя как целое число в переменной.

Мои попытки приводят к следующей ошибке: «фатальная ошибка: неожиданно найден ноль при развертывании необязательного значения»

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

var intNumber: Int = 0
@IBOutlet weak var txt_Number: UITextField!

for view in self.view.subviews as [UIView]{
if let txt = view as? UITextField
{
    if let txtData = txt.text where txtData.isEmpty
    {
        // Error Message
    }
    else
    {
        intNumber = Int(txt_Number.text)
    }
}
}

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

Заранее спасибо за любую помощь!


person Darth Washington    schedule 05.02.2016    source источник


Ответы (4)


Пара мыслей:

  1. Убедитесь, что ваша розетка подключена к txt_Number. Вся эта проверка кода, чтобы убедиться, что это не nil, не требуется, если (а) это выход, который вы подключили в IB; и (b) вы не выполняете приведенный выше код до полной загрузки представления (т.е. вызывается viewDidLoad).

    Если розетка не подключена, вы увидите пустую точку на левом поле:

    введите здесь описание изображения

    Если он подключен правильно, вы увидите закрашенную точку на левом поле:

    введите здесь описание изображения

  2. Если все подключено правильно, вы можете просто сделать:

    guard let txtData = txt_Number.text, let value = Int(txtData) else {
        // report error and then `return`
        return
    }
    
    intNumber = value
    
  3. Если вы хотите пофантазировать, вы можете убедиться, что пользователь вводит только числовые значения,

    • В viewDidLoad укажите, что клавиатура предназначена только для десятичных чисел.

      txt_Number.keyboardType = .NumberPad
      

      Или вы можете указать это и в IB.

    • Укажите делегата для текстового поля и разрешите ему вводить только числовые значения. (Это может показаться излишним, исходя из предыдущего пункта, но это не так, потому что вы также должны предвидеть, что они вставят строку в текстовое поле.)

    См. https://stackoverflow.com/a/26940387/1271826.

person Rob    schedule 05.02.2016
comment
Лучше сказать ему использовать intNumber = Int(txtData) ?? 0, чтобы мы могли предотвратить вопрос о необязательной ошибке :). - person Eendje; 05.02.2016
comment
@Eendje - Согласен. Или используйте оператор guard, который соответствующим образом присваивает значение. - person Rob; 05.02.2016

Для начала вам не нужно перебирать subviews, если у вас есть прямая ссылка txt_Number, но это не суть вашего вопроса.

Семантика if let позволит вам развернуть любые необязательные скобки {}, поэтому наиболее очевидным решением здесь является:

if let unwrappedString = txt_Number.text {
    if let unwrappedIntegerInit = Int(unwrappedString) {
        intNumber = unwrappedIntegerInit
    }
}

Мой полный пример с игровых площадок:

var intNumber: Int = 0
var txt_Number: UITextField = UITextField()
txt_Number.text = "12"

if let unwrappedString = txt_Number.text {
    if let unwrappedIntegerInit = Int(unwrappedString) {
        intNumber = unwrappedIntegerInit
    }
}

print(intNumber)

Или вы можете использовать охрану внутри функции:

func parse() {
    guard let text = txt_Number.text, let number = Int(text) else { return } // no text
    intNumber = number
}

СОВЕТ. Вы должны развернуть txt_Number.text и Int(text) отдельно, потому что Int(text) должен иметь необязательный аргумент.

person Radosław Cięciwa    schedule 05.02.2016

Вы пробовали с этим?

if let txtData = txt.text where !txtData.isEmpty
{
    intNumber = Int(txtData)
}
else
{
    // Error Message
}

ДОБАВИТЬ:

Функция Int() возвращает Optional. Если вы уверены, что значение правильное, вы можете принудительно развернуть, используя ! в конце имени переменной (когда вы ее используете), в противном случае просто поставьте вопросительный знак ?

person Luca D'Alberti    schedule 05.02.2016
comment
Я сделал, я получаю следующую ошибку: Значение необязательного типа «Int?» не развернутый; Вы хотели использовать '!' или '?'? - person Darth Washington; 05.02.2016
comment
Функция Int() возвращает Optional. Если вы уверены, что значение правильное, вы можете принудительно развернуть, используя ! в конце имени переменной (когда вы ее используете), в противном случае просто поставьте вопросительный знак ? - person Luca D'Alberti; 05.02.2016

попробовал ниже код, чтобы присвоить значение TextField переменной типа float, и все ошибки исчезли, как по волшебству

@IBOutlet weak var txtamount: UITextField!
@IBOutlet weak var txtrate: UITextField!
@IBOutlet weak var txtyear: UITextField!

@IBOutlet weak var lblresult: UILabel!
@IBAction func btncalculate(_ sender: UIButton)
{
    print("button is clicked")
    var amount,rate,year,answer : Float

    amount = Float(txtamount.text!)!
    rate = Float(txtrate.text!)!
    year = Float(txtyear.text!)!

    answer = (amount * rate * year) / 100.0
}
person user3819360    schedule 01.11.2016