Converti String in Float in Swift


101

Sto cercando di convertire i numeri presi da un UITextField, che presumo, siano in realtà stringhe e convertirli in Float, in modo da poterli moltiplicare.

Ho due messaggi UITextfieldche vengono dichiarati come segue:

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

Quando l'utente preme un pulsante UIB voglio calcolare il salario che l'utente guadagna, ma non posso, poiché devo prima convertirli in float, prima di poterli utilizzare.

So come convertirli in un numero intero in questo modo:

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

Tuttavia, non ho idea di come convertirli in float.

Risposte:


200

Swift 2.0+

Ora con Swift 2.0 puoi semplicemente usare Float(Wage.text)che restituisce un Float?tipo. Più chiara della soluzione di seguito che ritorna 0.

Se vuoi un 0valore per un non valido Floatper qualche motivo puoi usare Float(Wage.text) ?? 0che tornerà 0se non è valido Float.


Vecchia soluzione

Il modo migliore per gestire questo è il casting diretto:

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

In realtà ho creato un extensionper utilizzare meglio anche questo:

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

Ora puoi semplicemente chiamare var WageConversion = Wage.text.floatValuee consentire all'estensione di gestire il ponte per te!

Questa è una buona implementazione poiché può gestire i float effettivi (input con .) e aiuterà anche a impedire all'utente di copiare del testo nel campo di input ( 12p.34o anche 12.12.41).

Ovviamente, se Apple aggiunge un floatValuea Swift, verrà generata un'eccezione, ma nel frattempo potrebbe essere carino. Se lo aggiungono in un secondo momento, tutto ciò che devi fare per modificare il tuo codice è rimuovere l'estensione e tutto funzionerà senza problemi, dal momento che stai già chiamando .floatValue!

Inoltre, le variabili e le costanti dovrebbero iniziare con una minuscola (incluso IBOutlets)


L'estensione non è richiesta, il bridge viene eseguito automaticamente da Swift, poiché @tom afferma che tutto ciò di cui hai bisogno è Wage.text.floatValue. Non sono sicuro che sia cambiato tra la risposta pubblicata e ora, ma è lì da un po '.
sketchyTech

3
@ GoodbyeStackOverflow, sto usando Beta 4 e sicuramente non funziona. Forse l'hanno cambiato nella Beta 5? NSStringha floatValueestensione ma Stringno. Ottieni errore:'String' does not have member named floatValue
Firo

Questa potrebbe essere la ragione. Inoltre, hai Import Foundation all'inizio del tuo file?
sketchyTech

Non lo considero molto sicuro, almeno per gli standard Swift, poiché se la stringa non è un numero, NSString.floatValue restituisce solo 0. Ciò dovrebbe attivare un'eccezione o almeno restituire nil.
Ixx

let floatValue = (Float)(Wage.text)... In Swift 2.0
TheTiger

23

Perché in alcune parti del mondo, ad esempio, viene utilizzata una virgola al posto di un decimale. È meglio creare un NSNumberFormatter per convertire una stringa in float.

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

18

Converto String in Float in questo modo:

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

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

Penso che questa sia la soluzione migliore (almeno per swift 4+), il motivo principale è che restituisce un optional (al contrario di NSString.floatValue, che semplicemente restituisce 0se qualcosa non va). Nota che è NSNumberFormatterstato cambiato NumberFormatter.
Rom

9

Aggiornare

La risposta accettata mostra un modo più aggiornato di fare

Swift 1

Ecco come Paul Hegarty ha mostrato nella classe CS193p di Stanford nel 2015:

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

Puoi persino creare una proprietà calcolata per non doverlo fare ogni volta

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

5

Utilizzando la soluzione accettata, stavo scoprendo che il mio "1.1" (quando si utilizzava la conversione .floatValue) sarebbe stato convertito in 1.10000002384186, che non era quello che volevo. Tuttavia, se invece usassi .doubleValue, otterrei l'1,1 che volevo.

Quindi, ad esempio, invece di utilizzare la soluzione accettata, ho usato invece questa:

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

Nel mio caso non avevo bisogno della doppia precisione, ma l'utilizzo di .floatValue non mi dava il risultato corretto.

Volevo solo aggiungere questo alla discussione nel caso in cui qualcun altro avesse riscontrato lo stesso problema.


5

Di seguito ti fornirà un Float opzionale, incolla a! alla fine se sai che è un Float, o usa if / let.

let wageConversion = Float(wage.text)

4

Ecco un adattamento di Swift 3 della soluzione di Paul Hegarty dalla risposta di rdprado, con l'aggiunta di alcuni controlli per gli optional (restituendo 0,0 se una qualsiasi parte del processo fallisce):

var wageFloat:Float = 0.0

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

A proposito, ho frequentato il corso CS193p di Stanford usando iTunes University quando ancora insegnava Objective-C.

Ho trovato Paul Hegarty un istruttore FANTASTICO e consiglio vivamente il corso a chiunque inizi come sviluppatore iOS in Swift !!!


1
Questa è l'unica risposta corretta per Swift 3 o versioni successive. È necessario utilizzare a NumberFormatterper gestire i numeri in virgola mobile immessi dall'utente.
rmaddy

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

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

3
Spiega perché questo codice funziona. Ciò impedisce di copiare e incollare senza comprenderne il funzionamento.
rayryeng

3

In swift 4

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

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


1

Hai due opzioni che sono abbastanza simili (per approccio e risultato):

// 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
bridgeToObjectiveC () è stato rimosso nella Beta 5
carmen_munich

1

Double() costruisce un Double da un Int, in questo modo:

var convertedDouble = Double(someInt)

Nota che questo funzionerà solo se il tuo testo contiene effettivamente un numero. Poiché Wageè un campo di testo, l'utente può inserire quello che vuole e questo innescherà un errore di runtime quando si va a decomprimere l'Opzionale restituito da toInt(). È necessario verificare che la conversione sia riuscita prima di forzare l'unboxing.

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

Modificare:

Se sei sicuro che il testo sarà un numero intero, puoi fare qualcosa di simile (nota che textsu UITextField è anche Opzionale)):

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

Bene, sto solo consentendo all'utente di inserire numeri poiché la tastiera è un tastierino decimale, quindi non possono effettivamente inserire altro che numeri.
Stephen Fox

1
wageConversionFloatnon sarà mai il float, si blocca direttamente se la stringa di input è una sorta di float come 234.56. come potrebbe essere una soluzione accettata / votata positivamente ...?
holex

Questa risposta non funziona se il testo contiene un valore decimale. Esempio: questa risposta verrà restituita 3se il campo di testo ha 3.5. Questo perché il testo viene prima convertito in un Int, quindi Intviene convertito in un Float.
rmaddy

1
@StephenFox Tieni presente che un utente può incollare testo non numerico nel campo di testo o l'utente può avere una tastiera esterna. Non fare mai affidamento solo sulla tastiera per garantire l'immissione dei dati.
rmaddy

in realtà funziona, con numeri interi, ma non con i decimali. un decimale genererà un errore fatale!
Miles Works

1

Ho trovato un altro modo per prendere un valore di input di un UITextField e lanciarlo su un float:

    var tempString:String?
    var myFloat:Float?

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

1

Puoi usare,

let wg = Float(wage.text!)

Se vuoi arrotondare il float a 2 cifre decimali:

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

0

È così che mi sono avvicinato. Non volevo "attraversare il ponte", in quanto è stato comunque rimosso da Xcode 6 beta 5, veloce e sporco:

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
Perché in alcune parti del mondo, ad esempio, viene utilizzata una virgola al posto di un decimale. È meglio creare un NSNumberFormatter per convertire una stringa in float. Guarda @DmitriFuerle Answer
carmen_munich

@PartiallyFrozenOJ Hai provato la toDouble()funzione con la stringa "10", voglio dire se non ci sono decimali. Si bloccherà comunque. Perché in quel caso il conteggio sarà 1 e non lo gestirai. Si bloccherà a else if comps[0] == "" || comps[1] == "". Comunque sei così serio nella conversione.
TheTiger

@PartiallyFrozenOJ Ma se le condizioni fossero le stesse anche nel 2014. Comunque nessun problema!
TheTiger

0

Per motivi di completezza questa è una soluzione che utilizza un'estensione di UITextField quale può anche considerare una diversa localizzazione.

Per 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
    }
}

Come soluzione generale, questo dovrebbe probabilmente restituire a Float?e non trattare i valori non validi come 0.0. Lascia che il chiamante faccia qualcosa come let val = field.floatValue ?? 0.0se un dato caso dovesse trattare il risultato negativo come zero.
rmaddy

0

Swift 4/5, usa solo Float (valore).

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Risposta: 123200


-1

Usa questo:

 // 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
bridgeToObjectiveC () è stato rimosso nella Beta 5
carmen_munich

-4

Modo semplice:

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

puoi usare lo stesso approccio per altri calcoli, spero che questo aiuto !!


3
Per quanto grande sia, stava chiedendofloat
Jack il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.