Конвертировать строку, чтобы плавать в Apple, Swift

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

У меня два UITextfields, которые объявлены следующим образом:

@IBOutlet var wage: UITextField
@IBOutlet var hour: UITextField

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

Я знаю, как преобразовать их в целое число, выполнив это:

var wageConversion:Int = 0
wageConversion = wage.text.toInt()!

Тем не менее, я понятия не имею, как преобразовать их в поплавки.

22 ответа

Решение

Swift 2.0+

Теперь с Swift 2.0 вы можете просто использовать Float(Wage.text) который возвращает Float? тип. Более понятное, чем приведенное ниже решение, которое просто возвращает 0,

Если вы хотите 0 значение для недействительного Float по какой-то причине вы можете использовать Float(Wage.text) ?? 0 который вернется 0 если это не является действительным Float,


Старое решение

Лучший способ справиться с этим - прямое литье:

var WageConversion = (Wage.text as NSString).floatValue

Я на самом деле создал extension чтобы лучше использовать это тоже:

extension String {
    var floatValue: Float {
        return (self as NSString).floatValue
    }
}

Теперь вы можете просто позвонить var WageConversion = Wage.text.floatValue и позвольте удлинителю обработать мост для вас!

Это хорошая реализация, поскольку она может обрабатывать фактические числа с плавающей запятой (ввод с .), а также поможет предотвратить копирование текста пользователем в поле ввода (12p.34, или даже 12.12.41).

Очевидно, что если Apple добавит floatValue для Свифта это вызовет исключение, но в то же время это может быть приятно. Если они добавят его позже, то все, что вам нужно сделать, чтобы изменить ваш код, это удалить расширение, и все будет работать без проблем, так как вы уже будете звонить .floatValue!

Кроме того, переменные и константы должны начинаться со строчной буквы (включая IBOutlets)

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

let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
let number = numberFormatter.numberFromString(self.stringByTrimmingCharactersInSet(Wage.text))

Я конвертирую String в Float следующим образом:

let numberFormatter = NSNumberFormatter()
let number = numberFormatter.numberFromString("15.5")
let numberFloatValue = number.floatValue

println("number is \(numberFloatValue)") // prints "number is 15.5"

Обновить

Принятый ответ показывает более современный способ сделать

Свифт 1

Вот как Пол Хегарти показал в классе Стэнфорда CS193p в 2015 году:

wageConversion = NSNumberFormatter().numberFromString(wage.text!)!.floatValue

Вы даже можете создать вычисляемое свойство, чтобы не делать это каждый раз

var wageValue: Float {
        get {
            return NSNumberFormatter().numberFromString(wage.text!)!.floatValue
        }
        set {
            wage.text = "\(newValue)"
        }
    }

Ниже приведу опциональный поплавок, воткни! в конце, если вы знаете, что это Float, или используйте if/let.

let wageConversion = Float(wage.text)

Используя принятое решение, я обнаружил, что мой "1.1" (при использовании преобразования.floatValue) будет преобразован в 1.10000002384186, что было не тем, что я хотел. Однако, если бы я использовал вместо этого.doubleValue, я бы получил 1.1, который хотел.

Так, например, вместо того, чтобы использовать принятое решение, я использовал это вместо:

var WageConversion = (Wage.text as NSString).doubleValue

В моем случае мне не требовалась двойная точность, но использование.floatValue не давало мне должного результата.

Просто хотел добавить это к обсуждению на случай, если кто-то еще столкнулся с той же проблемой.

Вот Swift 3 адаптация решения Пола Хегарти из ответа rdprado с некоторой проверкой добавленных опций (возвращая 0.0, если какая-либо часть процесса завершается неудачей):

var wageFloat:Float = 0.0

if let wageText = wage.text {
    if let wageNumber = NumberFormatter().number(from: wageText) {
        wageFloat = wageNumber.floatValue
    }
}

Кстати, я брал урок по Стэнфорду CS193p в Университете iTunes, когда он еще преподавал Objective-C.

Я нашел Пола Хегарти инструктором FANTASTIC, и я очень рекомендую этот класс всем, кто начинает работать на iOS в Swift!!!

extension String {    
    func floatValue() -> Float? {
        if let floatval = Float(self) {
            return floatval
        }
        return nil
    }
}
import Foundation
"-23.67".floatValue // => -23.67

let s = "-23.67" as NSString
s.floatValue // => -23.67

Свифт 4

let Totalname = "10.0" //Now it is in string

let floatVal  = (Totalname as NSString).floatValue //Now converted to float

Double() строит Double из Int, как это:

var convertedDouble = Double(someInt)

Обратите внимание, что это будет работать, только если ваш текст содержит число. поскольку Wage является текстовым полем, пользователь может ввести все, что он хочет, и это вызовет ошибку во время выполнения, когда вы идете, чтобы распаковать опцию, возвращенную из toInt(), Вы должны проверить, что преобразование прошло успешно, прежде чем приступить к распаковке.

if let wageInt = Wage.text?.toInt() {
    //we made it in the if so the conversion succeeded.
    var wageConversionDouble = Double(wageInt)
}

Редактировать:

Если вы уверены, что текст будет целым, вы можете сделать что-то вроде этого (обратите внимание, что text на UITextField тоже необязательно)):

if let wageText = Wage.text {
    var wageFloat = Double(wageText.toInt()!)
}
Works on Swift 5+

import Foundation

let myString:String = "50"
let temp = myString as NSString
let myFloat = temp.floatValue
print(myFloat)  //50.0
print(type(of: myFloat)) // Float

Я конвертирую String в Float таким образом:

      let wage:Float = Float(textField.text!)!

Ты можешь использовать,

let wg = Float(wage.text!)

Если вы хотите округлить число с плавающей запятой до двух знаков после запятой:

let wg = Float(String(format: "%.2f",wage.text!)

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

    var tempString:String?
    var myFloat:Float?

    @IBAction func ButtonWasClicked(_ sender: Any) {
       tempString = myUITextField.text
       myFloat = Float(tempString!)!
    }

У вас есть два варианта, которые очень похожи (по подходу и результату):

// option 1:
var string_1 : String = "100"
var double_1 : Double = (string_1 as NSString).doubleValue + 99.0

// option 2: 
var string_2 : NSString = "100"
// or:  var string_2 = "100" as NSString
var number_2 : Double = string_2.doubleValue;

Для полноты картины это решение, использующее расширение UITextField который также может рассмотреть другой язык.

Для Swift 3+

extension UITextField {
    func floatValue(locale : Locale = Locale.current) -> Float {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.locale = locale

        let nsNumber = numberFormatter.number(from: text!)
        return nsNumber == nil ? 0.0 : nsNumber!.floatValue
    }
}

Вот как я подошел к этому. Я не хотел "переходить мост", так как он все равно был удален из Xcode 6 beta 5, быстро и грязно:

extension String {

    // converting a string to double
    func toDouble() -> Double? {

        // split the string into components
        var comps = self.componentsSeparatedByString(".")

        // we have nothing
        if comps.count == 0 {
            return nil
        }
        // if there is more than one decimal
        else if comps.count > 2 {
            return nil
        }
        else if comps[0] == "" || comps[1] == "" {
            return nil
        }

        // grab the whole portion
        var whole = 0.0
        // ensure we have a number for the whole
        if let w = comps[0].toInt() {
            whole = Double(w)
        }
        else {
            return nil
        }

        // we only got the whole
        if comps.count == 1 {

            return whole

        }

        // grab the fractional
        var fractional = 0.0
        // ensure we have a number for the fractional
        if let f = comps[1].toInt() {

            // use number of digits to get the power
            var toThePower = Double(countElements(comps[1]))

            // compute the fractional portion
            fractional = Double(f) / pow(10.0, toThePower)

        }
        else {
            return nil
        }

        // return the result
        return whole + fractional
    }

    // converting a string to float
    func toFloat() -> Float? {

        if let val = self.toDouble() {
            return Float(val)
        }
        else {
            return nil
        }

    }

}


// test it out
var str = "78.001"

if let val = str.toFloat() {
    println("Str in float: \(val)")
}
else {
    println("Unable to convert Str to float")
}

// now in double
if let val = str.toDouble() {
    println("Str in double: \(val)")
}
else {
    println("Unable to convert Str to double")
}

для преобразования строки в Float в Xcode 11, поскольку предыдущие методы требуют модификации

      func stringToFloat(value : String) -> Float {
    let numberFormatter = NumberFormatter()
    let number = numberFormatter.number(from: value)
    let numberFloatValue = number?.floatValue
    return numberFloatValue!
}

Swift 4/5, используйте только Float(value).

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Ответ: 123200

Использовать этот:

 // get the values from text boxes
    let a:Double = firstText.text.bridgeToObjectiveC().doubleValue
    let b:Double = secondText.text.bridgeToObjectiveC().doubleValue

//  we checking against 0.0, because above function return 0.0 if it gets failed to convert
    if (a != 0.0) && (b != 0.0) {
        var ans = a + b
        answerLabel.text = "Answer is \(ans)"
    } else {
        answerLabel.text = "Input values are not numberic"
    }

Простой способ:

// toInt returns optional that's why we used a:Int?
let a:Int? = firstText.text.toInt()
let b:Int? = secondText.text.toInt()

// check a and b before unwrapping using !
if a && b {
    var ans = a! + b!
    answerLabel.text = "Answer is \(ans)"
} else {
    answerLabel.text = "Input values are not numberic"
}

Вы можете использовать тот же подход для других расчетов, надеюсь, это поможет!

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