Konvertieren Sie String in Float in Swift

101

Ich versuche, Zahlen aus einem UITextField zu konvertieren, von denen ich annehme, dass sie tatsächlich Strings sind, und sie in Float zu konvertieren, damit ich sie multiplizieren kann.

Ich habe zwei UITextfields, die wie folgt deklariert sind:

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

Wenn der Benutzer einen UIButton drückt, möchte ich die Löhne berechnen, die der Benutzer verdient, aber ich kann nicht, da ich sie zuerst in Floats konvertieren muss, bevor ich sie verwenden kann.

Ich weiß, wie man sie auf diese Weise in eine ganze Zahl konvertiert:

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

Ich habe jedoch keine Ahnung, wie ich sie in Floats umwandeln soll.

Stephen Fox
quelle

Antworten:

200

Swift 2.0+

Jetzt können Sie mit Swift 2.0 nur noch Float(Wage.text)einen Float?Typ verwenden, der einen Typ zurückgibt . Klarer als die unten stehende Lösung, die gerade zurückkehrt 0.

Wenn Sie aus irgendeinem Grund einen 0Wert für einen ungültigen Wert wünschen Float, können Sie diesen verwenden, Float(Wage.text) ?? 0der zurückgegeben wird, 0wenn er nicht gültig ist Float.


Alte Lösung

Der beste Weg, dies zu handhaben, ist das direkte Casting:

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

Ich habe tatsächlich eine erstellt extension, um dies auch besser zu nutzen:

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

Jetzt können Sie einfach anrufen var WageConversion = Wage.text.floatValueund der Nebenstelle erlauben, die Brücke für Sie zu erledigen!

Dies ist eine gute Implementierung, da sie tatsächliche Floats (Eingabe mit .) verarbeiten kann und auch dazu beiträgt, dass der Benutzer keinen Text in Ihr Eingabefeld ( 12p.34oder sogar 12.12.41) kopieren kann .

Wenn Apple floatValueSwift zu a hinzufügt , wird dies natürlich eine Ausnahme auslösen, aber es kann in der Zwischenzeit nett sein. Wenn sie es später hinzufügen, müssen Sie nur die Erweiterung entfernen, um Ihren Code zu ändern, und alles funktioniert nahtlos, da Sie bereits anrufen werden .floatValue!

Außerdem sollten Variablen und Konstanten mit Kleinbuchstaben beginnen (einschließlich IBOutlets).

Firo
quelle
Die Erweiterung ist nicht erforderlich, die Bridge wird automatisch von Swift ausgeführt, da @tom angibt, dass Sie lediglich Wage.text.floatValue benötigen. Ich bin mir nicht sicher, ob sich dies zwischen der Antwort und der Antwort geändert hat, aber es ist schon eine Weile da.
SketchyTech
3
@ GoodbyeStackOverflow, ich verwende Beta 4 und es funktioniert definitiv nicht. Vielleicht haben sie es in Beta 5 geändert? NSStringhat floatValueErweiterung aber Stringnicht. Fehler erhalten:'String' does not have member named floatValue
Firo
Dies könnte der Grund sein. Haben Sie auch Import Foundation oben in Ihrer Datei?
SketchyTech
Ich halte dies zumindest für Swift-Standards nicht für sehr sicher, da NSString.floatValue nur 0 zurückgibt, wenn die Zeichenfolge keine Zahl ist. Dies sollte eine Ausnahme auslösen oder zumindest Null zurückgeben.
Ixx
let floatValue = (Float)(Wage.text)... in Swift 2.0
TheTiger
23

Denn in einigen Teilen der Welt wird beispielsweise ein Komma anstelle einer Dezimalstelle verwendet. Es ist am besten, einen NSNumberFormatter zu erstellen, um eine Zeichenfolge in float umzuwandeln.

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

Ich konvertiere String auf diese Weise in Float:

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

println("number is \(numberFloatValue)") // prints "number is 15.5"
Mert
quelle
Ich denke, dies ist die beste Lösung (zumindest für Swift 4+). Der Hauptgrund dafür ist, dass ein optionales zurückgegeben wird (im Gegensatz zu NSString.floatValue, das einfach zurückgegeben wird, 0wenn etwas nicht stimmt). Beachten Sie, dass NSNumberFormattergeändert wurde NumberFormatter.
Rom
9

Aktualisieren

Die akzeptierte Antwort zeigt eine aktuellere Vorgehensweise

Schnell 1

So hat Paul Hegarty 2015 in Stanfords CS193p-Klasse gezeigt:

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

Sie können sogar eine berechnete Eigenschaft erstellen, um dies nicht jedes Mal tun zu müssen

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

Bei Verwendung der akzeptierten Lösung stellte ich fest, dass meine "1.1" (bei Verwendung der .floatValue-Konvertierung) in 1.10000002384186 konvertiert wurde, was nicht das war, was ich wollte. Wenn ich jedoch stattdessen den .doubleValue verwenden würde, würde ich die 1.1 erhalten, die ich wollte.

Anstatt zum Beispiel die akzeptierte Lösung zu verwenden, habe ich stattdessen Folgendes verwendet:

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

In meinem Fall brauchte ich keine doppelte Genauigkeit, aber die Verwendung von .floatValue brachte mir nicht das richtige Ergebnis.

Ich wollte dies nur zur Diskussion hinzufügen, falls jemand anderes auf dasselbe Problem gestoßen ist.

Yjo-jo
quelle
5

Unten erhalten Sie einen optionalen Float, kleben Sie ein! am Ende, wenn Sie wissen, dass es sich um einen Float handelt, oder verwenden Sie if / let.

let wageConversion = Float(wage.text)
Bandejapaisa
quelle
4

Hier ist eine Swift 3-Anpassung der Lösung von Paul Hegarty aus der Antwort von rdprado, wobei einige nach Optionen hinzugefügt wurden (Rückgabe von 0.0, wenn ein Teil des Prozesses fehlschlägt):

var wageFloat:Float = 0.0

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

Übrigens habe ich Stanfords CS193p-Kurs an der iTunes University besucht, als sie noch Objective-C unterrichtete.

Ich fand, dass Paul Hegarty ein FANTASTISCHER Lehrer ist, und ich kann die Klasse jedem empfehlen, der als iOS-Entwickler in Swift anfängt !!!

Carl Smith
quelle
1
Dies ist die einzig richtige Antwort für Swift 3 oder höher. Sie müssen a verwenden NumberFormatter, um mit vom Benutzer eingegebenen Gleitkommazahlen umzugehen.
rmaddy
3
import Foundation
"-23.67".floatValue // => -23.67

let s = "-23.67" as NSString
s.floatValue // => -23.67
Tom
quelle
3
Erklären Sie, warum dieser Code funktioniert. Dies verhindert das Kopieren und Einfügen, ohne die Funktionsweise zu verstehen.
Rayryeng
3

In schneller 4

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

let floatVal  = (Totalname as NSString).floatValue //Now converted to float
Raghib Arshi
quelle
3
extension String {    
    func floatValue() -> Float? {
        return Float(self)
    }
}
FlowUI. SimpleUITesting.com
quelle
1
warum nicht einfach return Float(self)?
Leo Dabus
1

Sie haben zwei Optionen, die (nach Ansatz und Ergebnis) sehr ähnlich sind:

// 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;
Michael Dorner
quelle
2
bridgeToObjectiveC () wurde in Beta 5
carmen_munich
1

Double() erstellt ein Double aus einem Int wie folgt:

var convertedDouble = Double(someInt)

Beachten Sie, dass dies nur funktioniert, wenn Ihr Text tatsächlich eine Nummer enthält. Da Wagees sich um ein Textfeld handelt, kann der Benutzer eingeben, was er möchte, und dies löst einen Laufzeitfehler aus, wenn Sie die Option entfernen, von der die Option zurückgegeben wurde toInt(). Sie sollten überprüfen, ob die Konvertierung erfolgreich war, bevor Sie das Unboxing erzwingen.

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

Bearbeiten:

Wenn Sie sicher sind, dass der Text eine Ganzzahl ist, können Sie textFolgendes tun (beachten Sie, dass UITextField auch optional ist)):

if let wageText = Wage.text {
    var wageFloat = Double(wageText.toInt()!)
}
Lanze
quelle
Nun, ich erlaube dem Benutzer nur die Eingabe von Zahlen, da es sich bei der Tastatur um ein Dezimalfeld handelt, sodass er nur Zahlen eingeben kann.
Stephen Fox
1
wageConversionFloatwird niemals der Float sein, er stürzt direkt ab, wenn die Eingabezeichenfolge eine Art Float ist 234.56. Wie könnte es eine akzeptierte / hochgestufte Lösung sein ...?
Holex
Diese Antwort funktioniert nicht, wenn der Text einen Dezimalwert enthält. Beispiel - Diese Antwort wird zurückgegeben, 3wenn das Textfeld hat 3.5. Dies liegt daran, dass der Text zuerst in a konvertiert wird Intund dann Intin a konvertiert wird Float.
rmaddy
1
@StephenFox Beachten Sie, dass ein Benutzer nicht numerischen Text in das Textfeld einfügen kann oder über eine externe Tastatur verfügt. Verlassen Sie sich niemals nur auf die Tastatur, um die Dateneingabe zu gewährleisten.
rmaddy
Eigentlich funktioniert es mit ganzen Zahlen, nur nicht mit Dezimalstellen. Eine Dezimalstelle löst einen schwerwiegenden Fehler aus!
Miles Works
1

Ich habe einen anderen Weg gefunden, einen Eingabewert eines UITextField in einen Float umzuwandeln:

    var tempString:String?
    var myFloat:Float?

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

Sie können verwenden,

let wg = Float(wage.text!)

Wenn Sie den Gleitkomma auf 2 Dezimalstellen runden möchten:

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

So bin ich damit umgegangen. Ich wollte die Brücke nicht "überqueren", da sie ohnehin schnell und schmutzig aus Xcode 6 Beta 5 entfernt wurde:

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")
}
xBACP
quelle
1
Denn in einigen Teilen der Welt wird beispielsweise ein Komma anstelle einer Dezimalstelle verwendet. Es ist am besten, einen NSNumberFormatter zu erstellen, um eine Zeichenfolge in float umzuwandeln. Schauen Sie sich @DmitriFuerle Answer
carmen_munich
@PartiallyFrozenOJ Haben Sie versucht toDouble(), mit "10" zu funktionieren, meine ich, wenn es keine Dezimalstelle gibt. Es wird sowieso abstürzen. Denn in diesem Fall ist die Anzahl 1 und Sie behandeln das nicht. Es wird bei abstürzen else if comps[0] == "" || comps[1] == "". Wie auch immer, Sie sind so ernsthaft in der Bekehrung.
TheTiger
@PartiallyFrozenOJ Aber wenn der Zustand auch 2014 gleich war. Jedenfalls kein Problem!
TheTiger
0

Der Vollständigkeit halber handelt es sich hierbei um eine Lösung, bei deren Erweiterung UITextFieldauch ein anderes Gebietsschema berücksichtigt werden kann.

Für 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
    }
}
vadian
quelle
Als allgemeine Lösung sollte dies wahrscheinlich a zurückgeben Float?und ungültige Werte nicht als behandeln 0.0. Lassen Sie den Anrufer so etwas tun, als let val = field.floatValue ?? 0.0ob ein bestimmter Fall das schlechte Ergebnis als Null behandeln sollte.
rmaddy
0

Swift 4/5, benutze nur Float (Wert).

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Antwort: 123200

Krunal Patel
quelle
-1

Benutze das:

 // 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"
    }
Narendar Singh Saini
quelle
1
bridgeToObjectiveC () wurde in Beta 5
carmen_munich
-4

Einfacher Weg:

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

Sie können den gleichen Ansatz für andere Berechnungen verwenden, hoffe diese Hilfe!

Narendar Singh Saini
quelle
3
So großartig das auch ist, er bat umfloat
Jack