1

I have this code where the length and the width get multiplied but I need them to be 'Float' numbers and not 'integers'

// Outlets for square start
@IBOutlet weak var LengthForSquare: UITextField!
@IBOutlet weak var WidthForSquare: UITextField!
@IBOutlet weak var ResultForSquare: UILabel!
// Outlet for Square finish

@IBAction func AnswerForSquarePressed(_ sender: Any) {
    ResultForSquare.text = ((LengthForSquare.text! as NSString).integerValue * (WidthForSquare.text! as NSString).integerValue ).description
}

I want to convert the 'integerValue' to a float but it shows an error every time I try.

It would be great if someone can help me with this.

  • 1
    Show your attempt to use floatValue and tell us the error. – rmaddy Mar 20 '18 at 16:26
  • 1
    @the4kman While that is a duplicate, most of the answers are out-of-date or wrong. Make sure you follow an answer written in Swift 3 or later using a `NumberFormatter`. Currently there is only one truly correct answer and it has very few votes. – rmaddy Mar 20 '18 at 16:35

3 Answers3

3

Smart swifty solution which is not now covered in the linked duplicate, an extension of UITextField

extension UITextField {
    var floatValue : Float {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal

        let nsNumber = numberFormatter.number(from: text!)
        return nsNumber == nil ? 0.0 : nsNumber!.floatValue
    }
}

And use String(format rather than .description

ResultForSquare.text = String(format: "%.2f", LengthForSquare.floatValue * WidthForSquare.floatValue)

If the locale matters use also NumberFormatter to convert Float to String


Note: Please conform to the naming convention that variable names start with a lowercase letter.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • I'd write this answer for the duplicate and write a comment here that points to it. – Tamás Sengel Mar 20 '18 at 16:40
  • 2
    Does this work properly for all locales when users enter numbers in their appropriate format such as `1,23` or `1.23` or `1 000,45`, etc.? – rmaddy Mar 20 '18 at 16:41
  • I think floatValue should be nil if the string wasn't converted successfully. – vikingosegundo Mar 20 '18 at 16:43
  • @rmaddy Good catch, I updated the answer using `NumberFormatter ` – vadian Mar 20 '18 at 16:45
  • @vikingosegundo I followed the behavior in the question. `integerValue` / `floatValue` returns 0 if the string cannot be converted. – vadian Mar 20 '18 at 16:46
  • 2
    FYI - it is perfectly safe to force-unwrap the `text` property of `UITextField`. Is documented to return `""` even if you set it to `nil`. – rmaddy Mar 20 '18 at 16:47
  • Does `String(format:)` format based on locale? You should probably use `NumberFormatter` to format the result as well. – rmaddy Mar 20 '18 at 16:49
  • I wrote an answer to the [linked](https://stackoverflow.com/questions/24085665/convert-string-to-float-in-apples-swift) duplicate but as function with optional `Locale` parameter. – vadian Mar 20 '18 at 17:07
  • @rmaddy Can you send me the link where have you read the force unwrapping the `text` property of `UITextField` is safe even if we assign nil to it? – Syed Qamar Abbas Mar 21 '18 at 05:57
  • @SyedQamarAbbas Read the documentation for the `text` property of `UITextField`. Between that and a simple test the results in an empty string even after setting it to `nil`. – rmaddy Mar 21 '18 at 06:01
0

When converting a regular number contained in a string (i.e. one that isn't currency, etc) you don't need a number formatter:

let aString = "3.14159"
let defaultValue: Float = 0.0

let converted = Float(aString) ?? defaultValue

You can use whatever string you want in place of aString and you can replace defaultValue with whatever float value you want.

In the above example converted would end up being a float with the value 3.14159 in it. If however aString was something like "TARDIS" then converted would end up being 0.0. This way you know converted will always hold a value and you won't have to unwrap anything to get to it. (if you left off ?? defaultValue you would have to unwrap converted)

theMikeSwan
  • 4,739
  • 2
  • 31
  • 44
  • Yes, you do need a number formatter when the number was entered by a user and it might be in a different format such as `3,14` or `1.234,56`, etc. – rmaddy Mar 20 '18 at 17:37
  • Perhaps there is a radar that needs to be filed. Either the docs should mention that it can only handle English style number separation or the initializer should be updated to look at the current local and behave accordingly. (The docs show decimals for the ending separator but never mention that is the only one allowed…) – theMikeSwan Mar 20 '18 at 18:10
-1

Created extension for String and Int and simply use below written computed properties just like you use NSStringObject.intValue

extension String {
    var intValue: Int {
        if let value = Int(self) {
            return value
        }
        return 0// Set your default int value if failed to convert string into Int
    }
    var floatValue: Float {
        if let value = Float(self) {
            return value
        }
        return 0// Set your default float value if failed to convert string into float
    }
    var doubleValue: Double {
        if let value = Double(self) {
            return value
        }
        return 0// Set your default double value if failed to convert string into Double
    }
    var boolValue: Bool {
        if let value = Bool(self) {
            return value
        }
        return false// Set your default bool value if failed to convert string into Bool
    }
}
extension Int {
    var stringValue: String {
        return "\(self)"
    }
    var floatValue: Float {
        return Float(self)
    }
    var doubleValue: Double {
        return Double(self)
    }
}


@IBAction func AnswerForSquarePressed(_ sender: Any) {
    let area = (LengthForSquare.text.intValue * WidthForSquare.text.intValue)
    ResultForSquare.text = area.stringValue
}
Syed Qamar Abbas
  • 3,637
  • 1
  • 28
  • 52