garyc23
garyc23

Reputation: 21

How can properly use 'sender' argument in @UIAction code Swift?

I'm relatively new to Swift programming and just learned from this article on Stack Overflow that I can't change UIButton text via the 'sender' argument in @IBAction code, but must setup an @IBOutlet from the button and use methods on the outlet variable. How broad of a rule is that? What methods are OK to apply to the 'sender' argument, and which are not?

Upvotes: 1

Views: 3134

Answers (3)

Pierre Oleo
Pierre Oleo

Reputation: 1209

The sender argument you mention is part of the Target-Action Mechanism.

The sender parameter usually identifies the control sending the action message (although it can be another object substituted by the actual sender). The idea behind this is similar to a return address on a postcard. The target can query the sender for more information if it needs to. If the actual sending object substitutes another object as sender, you should treat that object in the same way. For example, say you have a text field and when the user enters text, the action method nameEntered: is invoked in the target:

As the sender could be substituded, there is no guarantee that someone could use another sender in the parameter if calling it manually, while if you own a reference to your button in your class, via an IBOutlet, then it could sometimes be wiser to use it for any method you expect to call as you are sure that it refers to the button.

However, if you are sure the method is only linked with the correct sender, you could potentially call any method.

The question would not as much be "what action can I call" but "am I really sure sender really is the relevent button"

Upvotes: 0

Dave Wood
Dave Wood

Reputation: 13323

I don't know what they're referring to in that post you've linked to, as it's not correct. You don't need an @IBOutlet for anything specifically. It doesn't grant any special powers to the button, it's just a handy pointer to the object you can use.

You of course need a pointer to the object if you want to call it's methods, but the sender attribute to an @IBAction is just as good for that IBAction's code.

You do have to make sure the sender is the right type.

For example:

@IBAction func buttonPressed(sender: UIButton) {
    sender.setTitle("New Title", forState: .Normal)
}

That will work fine and change the button tapped. Doesn't matter if there's an @IBOutlet pointing to it anywhere. The sender variable is all you need.

In some cases, you'll want to use an AnyObject type for sender, in which case you'll need to check the type first:

@IBAction func buttonPressed(sender: AnyObject) {
    if let button = sender as? UIButton {
        button.setTitle("New Title", forState: .Normal)
    }
}

Now, if you wanted to change a different button's title, then an @IBOutlet can make it easier.

@IBOutlet weak var someOtherButton: UIButton!

@IBAction func buttonPressed(sender: UIButton) {
    someOtherButton.setTitle("New Title", forState: .Normal)
}

But again, an @IBOutlet isn't required (it is recommended). To show @IBOutlet doesn't have any special powers, you could set a tag value (e.g. 100) on the button in Interface Builder and use code like this:

@IBAction func buttonPressed(sender: AnyObject) {
    if let button = view.viewWithTag(100) as? UIButton {
        button.setTitle("New Title", forState: .Normal)
    }
}

The 100 number I've used here is arbitrary and could be any number so long as you only use the number for one item in the view.

Upvotes: 2

Ketan Parmar
Ketan Parmar

Reputation: 27428

@IBAction func buttonClicked(sender : AnyObject) {
println("Button was clicked", sender)
}

here sender means your button's reference. you can perform different on button on click by using sender like sender.backgroundColor etc.

Hope this will help :)

Upvotes: 0

Related Questions