Duck
Duck

Reputation: 35973

Set attributed text to UIButton

I am trying to set an attributed string to a button.

The definition of this function on swift is this

func setAttributedTitle(_ title: NSAttributedString!,
               forState state: UIControlState)

so I thought I would have to type it like

myButton.setAttributedTitle(title:attrString, forState: UIControlState.Normal)

but the correct is

myButton.setAttributedTitle(attrString, forState: UIControlState.Normal)

why it is necessary to put forState: but not title? I don't get that.

And by the way what is the meaning of that underscore on the func definition?

Upvotes: 4

Views: 7582

Answers (1)

Gabriele Petronella
Gabriele Petronella

Reputation: 108131

Because that's how methods parameters work in swift. I emphasize methods, because this doesn't hold true for bare functions, i.e. func definitions outside a class scope.

By default the first parameter is given without an explicit name, which is instead mandatory for the others.

From the official guide

Methods in Swift are very similar to their counterparts in Objective-C. As in Objective-C, the name of a method in Swift typically refers to the method’s first parameter using a preposition such as with, for, or by, as seen in the incrementBy method from the preceding Counter class example. The use of a preposition enables the method to be read as a sentence when it is called. Swift makes this established method naming convention easy to write by using a different default approach for method parameters than it uses for function parameters.

Specifically, Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default. This convention matches the typical naming and calling convention you will be familiar with from writing Objective-C methods, and makes for expressive method calls without the need to qualify your parameter names.

The underscore means: this parameter has no external parameter name. For the first arguments of methods this is redundant, but you can use it for instance to change the default behavior discussed above.

For instance

class Foo {
    func bar(a: String, b: Int) {}
    func baz(a: String, _ b: Int) {}
}

will result in the following proper use of method calls:

var f = Foo()
f.bar("hello", b: 1)
f.baz("hello", 1)

Adding the _ has the effect of making b a local name only, so you cannot do

f.baz("hello", b: 1)

Upvotes: 3

Related Questions