MackTuesday
MackTuesday

Reputation: 543

Why does my IBAction function need a parameter?

In the code below, fahrenheitFieldEditingChanged() is called as expected if it has the parameter

textField: UITextField

If I remove the parameter from the function, it doesn't seem to be called, even though I delete the connection from the old function prototype and recreate it for the new one. I know it isn't being called because I added this line at the beginning of the function, and the change doesn't happen no matter what I do:

celsiusLabel.text = "?????"

Please help? Here's my code. (And why do I care about the parameter? I was hoping I could just refer to my IBOutlet textField, which should be the same object as what would be passed to the edit change function, since my storyboard only has one UITextField in it.)

import Foundation
import UIKit

class ConversionViewController: UIViewController {

    @IBOutlet var celsiusLabel: UILabel!
    @IBOutlet var textField: UITextField!

    var fahrenheitValue: Double? {
        didSet {
            updateCelsiusLabel()
        }
    }

    var celsiusValue: Double? {
        if let value = fahrenheitValue {
            return (value - 32) * 5/9
        }
        else {
            return nil
        }
    }

    func updateCelsiusLabel() {
        if let value = celsiusValue {
            celsiusLabel.text = "\(value)"
        }
        else {
            celsiusLabel.text = "???"
        }
    }

    @IBAction func fahrenheitFieldEditingChanged() {
        if let text = textField.text {
            if let value = Double(text) {
                fahrenheitValue = value
            }
            else {
                fahrenheitValue = nil
            }
        }
    }

    @IBAction func dismissKeyboard(sender: AnyObject) {
        textField.resignFirstResponder()
    }

}

Upvotes: 0

Views: 134

Answers (1)

matt
matt

Reputation: 535118

This has nothing to do with the presence or absence of the parameter (though, I should add, having the parameter is very good practice and you should stick to it, even though you have just the one text field).

Here's what's really going on. As you can see from this screen shot, a text field emits action messages on many different control events:

enter image description here

The one you want to connect to fahrenheitFieldEditingChanged is "Editing Changed". That's the one that fires every times the user changes the text. If you connect a different control event, fahrenheitFieldEditingChanged will be called for that control event, which will not be what you want.

Similarly, if you create the action connection by control dragging to code, the dialog offers to create the connection for the wrong action:

enter image description here

If you don't change Editing Did End to Editing Changed before you hit Connect, bad things will happen down the road.

And unfortunately, when you connect to an existing action method, the dialog doesn't even appear! You just get a connection for the Editing Did End action. That is what happened to you when you disconnected and reconnected.

The moral: use the Connections inspector (my first screen shot) so you can drag from the correct control event in the first place.

Upvotes: 2

Related Questions