I'm following Apple's Swift/iOS tutorial and it features this line of code:
button.setImage( filledStarImage, forState: [UIControlState.Highlighted, UIControlState.Selected] )
But the definition of UIButton.setImage
's signature is:
public func setImage(image: UIImage?, forState state: UIControlState)
There is no overload of setImage
that accepts an [UIControlState]()
array.
Obviously some voodoo is going on, can anyone explain?
UIControlState conforms to the OptionSetType protocol, which provides convenience methods for handling BitwiseOperationsTypes. So it's not setImage that's being overloaded, but what looks like an array. See https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_OptionSetType_Protocol/index.html#//apple_ref/swift/intf/s:PSs13OptionSetType
In Swift, the
UIControlState
is not, per se, an enum, but actually a structure. From the language reference forUIControl
:The key here is the
OptionSetType
protocol (to whichUIControlState
conforms), which allows us to do "enum-like" access to the static structures properties, given that these have aRawValue
that is aBitwiseOperationsType
. E.g.:Have a look at the instance methods (see link to language ref below) made available by conforming to the
OptionsSetType
. In addition membership management (e.g..contains(...)
as above; also,.remove(...)
,.insert(..)
), neat set operations such asunion(...)
andintersect(...)
are also available.So to summarize; you are right that the
UIButton.setImage
signature asks forforState state: UIControlState
, but, due to theOptionSetType
protocol, the array-looking[UIControlState.Highlighted, UIControlState.Selected]
is in fact a valid argument for call to structure type parameterUIControlState
.Note also, as per my example above, that the structure name can be left out, so sending
[.Highlighted, .Selected]
asforState
argument would be just as fine.Reference & good reads: