-1

I'm used to C# and java, swift is definitely a different beast!

I've been struggling for hours trying to get this to work. It is something so simple as well! I just want to get the text from a UITextField and turn it into an Int and then send the Int to a UILabel!!

So many answers on the internet haven't worked at all!

This is the error i'm getting now. (using Xcode 8.2.1 and Swift 3.0.2)

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var firstTextField: UITextField!
    @IBOutlet weak var secondTextField: UITextField!
    @IBOutlet weak var sumLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func calculateButton(_ sender: UIButton) {
        let firstNumber = Int(firstTextField.text!)
        let secondNumber = Int(secondTextField.text!)

        //ERROR: 'init' has been renamed to 'init'(describing:)'
        sumLabel.text = String(firstNumber + secondNumber)
    }

}

Thanks guys!

jasperdunn
  • 81
  • 10

4 Answers4

1

First get the Int:

let firstNumber = Int(firstTextField.text!) ?? 0

The ?? 0 provides a default value when the text cannot be parsed to an Int.

Conversion back to String is simple:

sumLabel.text = String(firstNumber)

However, you might want to use NumberFormatter instead if you want to get grouping separators.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
0

Since you need a String for the second instance, you can simply have the code be:

@IBAction func calculateButton(_ sender: UIButton) {
    sumLabel.text = firstTextField.text!
}

But if you do some calculations first, then have the code like this:

@IBAction func calculateButton(_ sender: UIButton) {
    let firstNumber = Int(firstTextField.text!)
    sumLabel.text = "\(firstNumber)"
}

The part where you put the value in brackets with a \ before it is called string interpolation. Where you can have the value of most basic types like String, Int, Double, Date etc. be converted to a String.

And if you want to guard against the Int cast not working, perhaps because there were non-numeric characters in the text, you can do this or something similar:

@IBAction func calculateButton(_ sender: UIButton) {
    if let firstNumber = Int(firstTextField.text!) {
        sumLabel.text = "\(firstNumber)"
    }
}

Otherwise, the String interpolation will give you something like "Optional(125)"

You would also get a crash on the firstTextField.text! if the text field did not have any text :) So you might want to further refine to something like this:

@IBAction func calculateButton(_ sender: UIButton) {
    if let txt = firstTextField.text {
        if let firstNumber = Int(txt) {
            sumLabel.text = "\(firstNumber)"
        }
    }
}

This way, you ensure that you have a value at each stage before proceeding to the next instead of blindly assuming that there will be a value :)

And finally, if you do not have your text field hooked up in your storyboard, you could experience another crash at run time. You could protect against that by checking that the text field is not nil as follows:

@IBAction func calculateButton(_ sender: UIButton) {
    if let fld = firstTextField {
        if let txt = fld.text {
            if let firstNumber = Int(txt) {
                sumLabel.text = "\(firstNumber)"
            }
        }
    }
}
Fahim
  • 3,466
  • 1
  • 12
  • 18
  • I want to be able to do calculations with the integer of course :) I just wrote it like this to make it quicker to understand. I'll edit it :P – jasperdunn Mar 23 '17 at 12:22
  • Sorry, I was editing to explain that bit when you wrote your comment - I figured you did want to do some calculations after I took as second look :) – Fahim Mar 23 '17 at 12:25
  • I ended up with a fatal error: unexpectedly found nil while unwrapping an Optional value – jasperdunn Mar 23 '17 at 12:35
  • @Merlin On which line? – Fahim Mar 23 '17 at 12:37
  • if let text = firstTextField.text, – jasperdunn Mar 23 '17 at 12:39
  • Do you have the `firstTextField` outlet connected to the actual text field in your storyboard? – Fahim Mar 23 '17 at 12:43
  • how do I check that? I'm very new to swift so this could be it! :) – jasperdunn Mar 23 '17 at 12:46
  • In your view controller you should have an @IBOutlet declaration which specifies the outlet for your text field and that is where you'd be defining `firstTextField`. So first make sure that you have that. Then go to your storyboard, select the relevant view controller and go to the Connections Inspector. The outlet should show up there and you can see if it is connected and connect it to the actual text field on your storyboard if it is not. – Fahim Mar 23 '17 at 12:51
  • Fantastic! I must have somehow deleted the connection. Doh, thanks so much! :) – jasperdunn Mar 23 '17 at 12:55
  • Happy to be of help :) I've updated the answer as we progressed so that it covers all possibilities. If you think it's helpful. Please mark it as "correct" :) – Fahim Mar 23 '17 at 12:57
0

The problem is that firstNumber is optional and there is no String init function for optional Int. You have to unwrap first, then the code compiles. I also recommend to not force unwrap the text property.

@IBAction func calculateButton(_ sender: UIButton) {
    if let text = firstTextField.text,
      let firstNumber = Int(text) {
        sumLabel.text = String(firstNumber)
    }
}
Yannick
  • 3,210
  • 1
  • 21
  • 30
0

Turns out, my ViewController had lost its connection to both TextFields. I just had to go to the storyboard, select the ViewController and click and drag the outlets from the connections inspector to my code. Somehow I thought that @IBOutlet was the connection! Thanks

In the end, ALL of your answers now work! Shows how many different ways there are of doing the same thing! Scary

jasperdunn
  • 81
  • 10