web-dev-qa-db-fra.com

Convertir une chaîne pour flotter dans Swift d'Apple

J'essaie de convertir les nombres extraits d'un UITextField, ce qui, je suppose, sont en fait des chaînes, et de les convertir en float, afin que je puisse les multiplier.

J'ai deux UITextfields qui sont déclarés comme suit:

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

Lorsque l'utilisateur appuie sur une touche UIButton, je souhaite calculer le salaire gagné par l'utilisateur, mais je ne peux pas, car je dois d'abord les convertir en float avant de pouvoir les utiliser.

Je sais comment les convertir en un entier en procédant ainsi:

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

Cependant, je ne sais pas comment les convertir en float.

85
Stephen Fox

Swift 2.0+ 

Maintenant, avec Swift 2.0 vous pouvez simplement utiliser Float(Wage.text) qui renvoie un type Float?. Plus clair que la solution ci-dessous qui ne fait que retourner 0.

Si vous voulez une valeur 0 pour une Float invalide pour une raison quelconque, vous pouvez utiliser Float(Wage.text) ?? 0 qui retournera 0 s'il ne s'agit pas d'une Float valide.


Ancienne solution

La meilleure façon de gérer cela est le casting direct:

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

J'ai en fait créé une extension pour mieux l'utiliser aussi:

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

Maintenant, vous pouvez simplement appeler var WageConversion = Wage.text.floatValue et permettre à l'extension de gérer le pont pour vous!

Ceci est une bonne implémentation car il peut gérer les flottants réels (entrée avec .) et évitera également à l'utilisateur de copier du texte dans votre champ de saisie (12p.34, voire 12.12.41).

Évidemment, si Apple ajoute une floatValue à Swift, cela jettera une exception, mais cela pourrait être agréable entre-temps. S'ils l'ajoutent plus tard, tout ce que vous avez à faire pour modifier votre code est de supprimer l'extension. Tout fonctionnera de manière transparente, puisque vous appelez déjà .floatValue!

De plus, les variables et les constantes doivent commencer par une minuscule (incluant IBOutlets)

179
Firo

Parce que dans certaines parties du monde, par exemple, une virgule est utilisée à la place d'une décimale. Il est préférable de créer un NSNumberFormatter pour convertir une chaîne en float.

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

Je convertis String en Float de cette façon:

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

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

Mettre à jour

La réponse acceptée montre une façon de faire plus moderne

Swift 1

Voici comment Paul Hegarty a montré en 2015 sur la classe CS193p de Stanford:

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

Vous pouvez même créer une propriété calculée pour ne pas avoir à le faire à chaque fois

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

Vous trouverez ci-dessous un flotteur optionnel, collez-en un! à la fin si vous savez que c'est un Float, ou utilisez if/let. 

let wageConversion = Float(wage.text)
5
bandejapaisa

En utilisant la solution acceptée, je trouvais que mon "1.1" (en utilisant la conversion .floatValue) serait converti en 1.10000002384186, ce qui n’était pas ce que je voulais. Cependant, si j’utilisais plutôt .doubleValue, j’obtiendrais le 1.1 que je voulais.

Ainsi, par exemple, au lieu d'utiliser la solution acceptée, j'ai utilisé ceci à la place:

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

Dans mon cas, je n’avais pas besoin de la double précision, mais l’utilisation de .floatValue ne me donnait pas le bon résultat. 

Je voulais juste ajouter ceci à la discussion au cas où quelqu'un aurait été confronté au même problème.

5
Yjo-jo
import Foundation
"-23.67".floatValue // => -23.67

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

Voici une adaptation Swift 3 de la solution de Paul Hegarty à partir de la réponse de rdprado, avec quelques vérifications pour les options supplémentaires (renvoyant 0.0 si une partie du processus échoue):

var wageFloat:Float = 0.0

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

En passant, j'ai suivi le cours CS193p de Stanford avec iTunes University alors qu'il enseignait encore Objective-C. 

J'ai trouvé que Paul Hegarty était un instructeur FANTASTIQUE et je recommanderais vivement ce cours à quiconque débutant en tant que développeur iOS à Swift !!!

3
Carl Smith
extension String {    
    func floatValue() -> Float? {
        if let floatval = Float(self) {
            return floatval
        }
        return nil
    }
}

Vous avez deux options assez similaires (par l'approche et le résultat):

// 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;
1
Michael Dorner

J'ai trouvé un autre moyen de prendre une valeur d'entrée d'un UITextField et de la convertir en float:

    var tempString:String?
    var myFloat:Float?

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

Dans Swift 4

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

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

Par souci d’exhaustivité, il s’agit d’une solution utilisant une extension de UITextField qui peut également prendre en compte des paramètres régionaux différents.

Pour 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
    }
}
0
vadian

Voici comment je l'ai abordé. Je ne voulais pas "traverser le pont", car il a été retiré de Xcode 6 beta 5 de toute façon, rapide et sale:

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")
}
0
xBACP