Конвертировать строку, чтобы плавать в Apple, Swift
Я пытаюсь преобразовать числа, взятые из UITextField, которые, как я предполагаю, на самом деле являются строками, и преобразовать их в число с плавающей точкой, чтобы я мог их умножить.
У меня два UITextfield
s, которые объявлены следующим образом:
@IBOutlet var wage: UITextField
@IBOutlet var hour: UITextField
Когда пользователь нажимает кнопку UIB, я хочу вычислить заработную плату, которую он получает, но я не могу, поскольку мне нужно сначала преобразовать их в числа с плавающей запятой, прежде чем я смогу их использовать.
Я знаю, как преобразовать их в целое число, выполнив это:
var wageConversion:Int = 0
wageConversion = wage.text.toInt()!
Тем не менее, я понятия не имею, как преобразовать их в поплавки.
22 ответа
Swift 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
для Свифта это вызовет исключение, но в то же время это может быть приятно. Если они добавят его позже, то все, что вам нужно сделать, чтобы изменить ваш код, это удалить расширение, и все будет работать без проблем, так как вы уже будете звонить .floatValue
!
Кроме того, переменные и константы должны начинаться со строчной буквы (включая IBOutlets
)
Потому что, например, в некоторых частях света вместо десятичной запятой используется запятая. Лучше всего создать NSNumberFormatter для преобразования строки в число с плавающей точкой.
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
let number = numberFormatter.numberFromString(self.stringByTrimmingCharactersInSet(Wage.text))
Я конвертирую String в Float следующим образом:
let numberFormatter = NSNumberFormatter()
let number = numberFormatter.numberFromString("15.5")
let numberFloatValue = number.floatValue
println("number is \(numberFloatValue)") // prints "number is 15.5"
Обновить
Принятый ответ показывает более современный способ сделать
Свифт 1
Вот как Пол Хегарти показал в классе Стэнфорда CS193p в 2015 году:
wageConversion = NSNumberFormatter().numberFromString(wage.text!)!.floatValue
Вы даже можете создать вычисляемое свойство, чтобы не делать это каждый раз
var wageValue: Float {
get {
return NSNumberFormatter().numberFromString(wage.text!)!.floatValue
}
set {
wage.text = "\(newValue)"
}
}
Ниже приведу опциональный поплавок, воткни! в конце, если вы знаете, что это Float, или используйте if/let.
let wageConversion = Float(wage.text)
Используя принятое решение, я обнаружил, что мой "1.1" (при использовании преобразования.floatValue) будет преобразован в 1.10000002384186, что было не тем, что я хотел. Однако, если бы я использовал вместо этого.doubleValue, я бы получил 1.1, который хотел.
Так, например, вместо того, чтобы использовать принятое решение, я использовал это вместо:
var WageConversion = (Wage.text as NSString).doubleValue
В моем случае мне не требовалась двойная точность, но использование.floatValue не давало мне должного результата.
Просто хотел добавить это к обсуждению на случай, если кто-то еще столкнулся с той же проблемой.
Вот Swift 3 адаптация решения Пола Хегарти из ответа rdprado с некоторой проверкой добавленных опций (возвращая 0.0, если какая-либо часть процесса завершается неудачей):
var wageFloat:Float = 0.0
if let wageText = wage.text {
if let wageNumber = NumberFormatter().number(from: wageText) {
wageFloat = wageNumber.floatValue
}
}
Кстати, я брал урок по Стэнфорду CS193p в Университете iTunes, когда он еще преподавал Objective-C.
Я нашел Пола Хегарти инструктором FANTASTIC, и я очень рекомендую этот класс всем, кто начинает работать на iOS в Swift!!!
extension String {
func floatValue() -> Float? {
if let floatval = Float(self) {
return floatval
}
return nil
}
}
import Foundation
"-23.67".floatValue // => -23.67
let s = "-23.67" as NSString
s.floatValue // => -23.67
Свифт 4
let Totalname = "10.0" //Now it is in string
let floatVal = (Totalname as NSString).floatValue //Now converted to float
Double()
строит Double из Int, как это:
var convertedDouble = Double(someInt)
Обратите внимание, что это будет работать, только если ваш текст содержит число. поскольку Wage
является текстовым полем, пользователь может ввести все, что он хочет, и это вызовет ошибку во время выполнения, когда вы идете, чтобы распаковать опцию, возвращенную из toInt()
, Вы должны проверить, что преобразование прошло успешно, прежде чем приступить к распаковке.
if let wageInt = Wage.text?.toInt() {
//we made it in the if so the conversion succeeded.
var wageConversionDouble = Double(wageInt)
}
Редактировать:
Если вы уверены, что текст будет целым, вы можете сделать что-то вроде этого (обратите внимание, что text
на UITextField тоже необязательно)):
if let wageText = Wage.text {
var wageFloat = Double(wageText.toInt()!)
}
Works on Swift 5+
import Foundation
let myString:String = "50"
let temp = myString as NSString
let myFloat = temp.floatValue
print(myFloat) //50.0
print(type(of: myFloat)) // Float
Я конвертирую String в Float таким образом:
let wage:Float = Float(textField.text!)!
Ты можешь использовать,
let wg = Float(wage.text!)
Если вы хотите округлить число с плавающей запятой до двух знаков после запятой:
let wg = Float(String(format: "%.2f",wage.text!)
Я нашел другой способ взять входное значение UITextField и привести его к плавающей точке:
var tempString:String?
var myFloat:Float?
@IBAction func ButtonWasClicked(_ sender: Any) {
tempString = myUITextField.text
myFloat = Float(tempString!)!
}
У вас есть два варианта, которые очень похожи (по подходу и результату):
// 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;
Для полноты картины это решение, использующее расширение 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
}
}
Вот как я подошел к этому. Я не хотел "переходить мост", так как он все равно был удален из 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")
}
для преобразования строки в Float в Xcode 11, поскольку предыдущие методы требуют модификации
func stringToFloat(value : String) -> Float {
let numberFormatter = NumberFormatter()
let number = numberFormatter.number(from: value)
let numberFloatValue = number?.floatValue
return numberFloatValue!
}
Swift 4/5, используйте только Float(value).
let string_value : String = "123200"
let float_value : Float = Float(string_value)
print(float_value)
Ответ: 123200
Использовать этот:
// 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"
}
Простой способ:
// 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"
}
Вы можете использовать тот же подход для других расчетов, надеюсь, это поможет!