在Swift中将String转换为Float


101

我正在尝试转换从UITextField中获取的数字(我认为这些数字实际上是字符串),并将其转换为Float,以便可以对其进行乘法运算。

我有两个UITextfield声明如下:

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

当用户按下UIButton时,我想计算用户赚取的工资,但是我不能,因为我需要先将其转换为浮动工资,然后才能使用它们。

我知道如何通过执行以下操作将它们转换为整数:

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

但是,我不知道如何将它们转换为浮点数。

Answers:


200

迅捷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在Swift 中添加了,则会抛出异常,但与此同时可能会很好。如果他们以后再添加它,那么只需修改扩展名,您只需要做的就是删除扩展名,一切将无缝进行,因为您已经在调用了.floatValue

此外,变量和常量应以小写字母开头(包括IBOutlets


不需要扩展名,桥由Swift自动完成,因为@tom声明您需要的只是Wage.text.floatValue。不确定在发布答案和现在之间是否有所改变,但是已经存在了一段时间。
sketchyTech

3
@GoodbyeStackOverflow,我正在使用Beta 4,它肯定无法正常工作。也许他们在Beta 5中更改了它?NSStringfloatValue扩展名,但String没有。得到的错误:'String' does not have member named floatValue
Firo 2014年

这可能是原因。另外,您是否在文件顶部导入了Foundation?
sketchyTech

我认为这不是很安全,至少对于Swift标准而言,因为如果字符串不是数字,则NSString.floatValue只会返回0。这应该触发Exception或至少返回nil。
Ixx

let floatValue = (Float)(Wage.text)...在Swift 2.0
TheTiger中,2016年

23

因为例如在世界的某些地区,使用逗号代替小数。最好创建一个NSNumberFormatter来将字符串转换为float。

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

18

我以这种方式将String转换为Float:

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

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

我认为这是最好的解决方案(至少对于Swift 4+而言),主要原因是它返回了一个可选的(与相对NSString.floatValue0如果出现问题,它只会返回)。请注意NSNumberFormatter已更改NumberFormatter
罗姆

9

更新资料

接受的答案显示了更新的方法

斯威夫特1

这是Paul Hegarty在2015年斯坦福大学CS193p课程上的表现:

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

您甚至可以创建一个计算属性,而不必每次都这样做

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

5

使用公认的解决方案,我发现我的“ 1.1”(使用.floatValue转换时)将转换为1.10000002384186,这不是我想要的。但是,如果我改用.doubleValue,则将得到我想要的1.1。

因此,例如,我使用以下方法代替使用公认的解决方案:

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

就我而言,我不需要双精度,但是使用.floatValue不能给我正确的结果。

只是想将其添加到讨论中,以防其他人遇到同一问题。


5

下面将为您提供一个可选的Float,坚持一下!最后,如果您知道它是Float,则使用if / let。

let wageConversion = Float(wage.text)

4

这是rdprado回答的Paul Hegarty解决方案的Swift 3改编版,其中添加了一些对可选项的检查(如果过程的任何部分失败,则返回0.0):

var wageFloat:Float = 0.0

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

顺便说一句,我在仍在教授Objective-C的iTunes大学上斯坦福大学的CS193p课程。

我发现Paul Hegarty是一名FANTASTIC讲师,我强烈建议该班级向所有在Swift中作为iOS开发人员开始的人!


1
这是Swift 3或更高版本的唯一正确答案。您必须使用a NumberFormatter处理用户输入的浮点数。
rmaddy18年

3
import Foundation
"-23.67".floatValue // => -23.67

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

3
解释为什么此代码有效。这样可防止在不了解其操作的情况下进行复制和粘贴。
rayryeng 2014年



1

您有两个非常相似的选项(根据方法和结果):

// 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;

2
在Beta 5中删除了bridgeToObjectiveC()
carmen_munich 2014年

1

Double() 从一个Int构建一个Double,如下所示:

var convertedDouble = Double(someInt)

请注意,这仅在您的文本实际包含数字时才有效。由于Wage是一个文本字段,因此用户可以输入所需的任何内容,当您取消对从中返回的Optional装箱时,这将触发运行时错误toInt()。在强制取消装箱之前,您应该检查转换是否成功。

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

编辑:

如果确定文本为整数,则可以执行以下操作(请注意,textUITextField上的也是可选的):

if let wageText = Wage.text {
    var wageFloat = Double(wageText.toInt()!)
}

好吧,我只允许用户输入数字,因为小键盘是小数键盘,因此他们除了数字以外实际上不能输入其他任何内容。
Stephen Fox

1
wageConversionFloat永远不会是浮点数,如果输入字符串像一样的浮点数,它将直接崩溃234.56。怎么可能是一个被接受/赞成的解决方案...?
Holex 2014年

如果文本包含十进制值,则此答案无效。示例- 3如果文本字段包含,则此答案将返回3.5。这是因为文本首先转换为Int,然后将Int转换为Float
rmaddy14年

1
@StephenFox请记住,用户可以将非数字文本粘贴到文本字段中,或者用户可能具有外部键盘。切勿仅依靠键盘来确保输入数据。
rmaddy14年

实际上,它确实可以使用整数,但不能使用小数。小数点将引发致命错误!
Miles Works

1

我找到了另一种方法来获取UITextField的输入值并将其转换为浮点数:

    var tempString:String?
    var myFloat:Float?

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

1

您可以使用,

let wg = Float(wage.text!)

如果要将浮点数舍入到小数点后两位:

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

0

这就是我的方法。我不想“过桥”,因为它已经从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")
}

1
因为例如在世界的某些地区,使用逗号代替小数。最好创建一个NSNumberFormatter来将字符串转换为float。看看@DmitriFuerle答案
carmen_munich 2014年

@PartiallyFrozenOJ您是否尝试过toDouble()使用“ 10”字符串的功能,我的意思是如果没有小数。无论如何它都会崩溃。因为在这种情况下,计数将为1,而您不进行处理。它将在崩溃else if comps[0] == "" || comps[1] == ""。无论如何,您在转换方面是如此认真。
TheTiger

@PartiallyFrozenOJ但如果条件在2014年也一样。反正没问题!
TheTiger

0

为了完整起见,这是一个使用扩展的解决方案,该扩展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
    }
}

作为一般解决方案,这可能应该返回a Float?,而不将无效值视为0.0。让调用者执行某种操作,例如let val = field.floatValue ?? 0.0在给定的情况下应将不良结果视为零。
rmaddy


-1

用这个:

 // 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"
    }

1
在Beta 5中删除了bridgeToObjectiveC()
carmen_munich 2014年

-4

简单的方法:

// 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"
}

您可以使用相同的方法进行其他计算,希望对您有所帮助!


3
这么好,他要的是float
杰克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.