Junsan
Junsan

Reputation: 1

Unresolved Identifier error within @IBAction func

I am writing a basic iOS app to test my Swift knowledge and keep on practicing. In my app the user types a name for a baby, then turns a switch either on or off to set the gender/sex and also change the system color. After that, the name is used to fill in a UITextView, named "firstWords", in the following block of code:

// Save name entered into text field
@IBAction func saveSettings(_ sender: UIButton) {
    nameLabel.text = nameTextField.text
    if nameTextField.text == "" {
        showMessage()
        nameLabel.text = "Baby Name"
    }
    nameTextField.resignFirstResponder()
    let nameHolder: String! = nameLabel.text
    if boyGirlSwitch.isOn {
        let sex = ("boy", "his", "he", "Boy", "His", "He")
    } else {
        let sex = ("girl", "her", "she", "Girl", "Her", "She")
    }
    firstWords.text = "Wow, " + nameHolder + " has so much to look forward to!" + (sex.5) + " will do so many great things!"
}

I keep getting an error at the tuple (sex.5) inside firstWords that says: "Use of unresolved identifier 'sex'"

As I understand it, the constant sex is declared within the if statement and the compiler does go through it either way, so it does get identified and declared. QUESTION: Why am I getting the error?

Thanks in advance! Here's a screenshot of my code as well: Screenshot of block of code as described above, including the compiler/build-error

Upvotes: 0

Views: 203

Answers (1)

Sebastian Flückiger
Sebastian Flückiger

Reputation: 5555

This is a scope issue. sex is only available within the else clause.

You can fix it like this

// Save name entered into text field
@IBAction func saveSettings(_ sender: UIButton) {
    nameLabel.text = nameTextField.text
    if nameTextField.text == "" {
        showMessage()
        nameLabel.text = "Baby Name"
    }
    nameTextField.resignFirstResponder()
    let nameHolder: String! = nameLabel.text
    var sex : (String, String, String, String, String, String)
    if boyGirlSwitch.isOn {
        sex = ("boy", "his", "he", "Boy", "His", "He")
    } else {
        sex = ("girl", "her", "she", "Girl", "Her", "She")
    }
    firstWords.text = "Wow, " + nameHolder + " has so much to look forward to!" + (sex.5) + " will do so many great things!"
}

this way sex is defined within the scope of the whole IBAction and will be available in the end.

you could also skip one condition if you pre-declare it with a default:

// Save name entered into text field
@IBAction func saveSettings(_ sender: UIButton) {
    nameLabel.text = nameTextField.text
    if nameTextField.text == "" {
        showMessage()
        nameLabel.text = "Baby Name"
    }
    nameTextField.resignFirstResponder()
    let nameHolder: String! = nameLabel.text
    var sex = ("girl", "her", "she", "Girl", "Her", "She")
    if boyGirlSwitch.isOn {
        sex = ("boy", "his", "he", "Boy", "His", "He")
    }
    firstWords.text = "Wow, " + nameHolder + " has so much to look forward to!" + (sex.5) + " will do so many great things!"
}

There is actually a nice article about variable scope on Wikipedia: https://en.wikipedia.org/wiki/Scope_(computer_science)

Upvotes: 2

Related Questions