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 UITextfield
s 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.
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.
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
)
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))
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"
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)"
}
}
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)
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.
import Foundation
"-23.67".floatValue // => -23.67
let s = "-23.67" as NSString
s.floatValue // => -23.67
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 !!!
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;
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!)!
}
Dans Swift 4
let Totalname = "10.0" //Now it is in string
let floatVal = (Totalname as NSString).floatValue //Now converted to float
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
}
}
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")
}