【swift】UIButtonのタイトルを設定する時のステートをUIControlState()とするのは何?

もくじ

毎度どうもこんにちは。iOSをメインに開発しているロッキーカナイです。

今日は以前から疑問に思っていた事を書きたいと思います。タイトルにもある通り、「UIButtonのタイトルを設定する時のステートをUIControlState()とするのは何?」です。Swiftの参考サイトや、プロジェクトのソースを見ていて、何だろ?とは思っていたのですが、調べたのでまとめてみたいと思います。

let button = UIButton()
button.setTitle("normal", for: UIControlState())
self.view.addSubview(button)

UIButtonにタイトルを適応させる場合、setTitle(_ title: String?, for state: UIControlState)メソッドを使用するのですが、第1引数にはタイトルテキストを指定し、第二引数には状態を管理している構造体のUIControlStateを指定します。普通であれば、状態データを指定するはずですが、よくUIControlState()としているのを見かけます。これが疑問でした。

ちなみに、UIControlStateデータは、以下のようになってます。

public struct UIControlState : OptionSet {
    public init(rawValue: UInt)
    public static var normal: UIControlState { get }
    public static var highlighted: UIControlState { get }
    public static var disabled: UIControlState { get }
    public static var selected: UIControlState { get } 
    ...省略
}

つまり、button.setTitle(“normal”, for: .normal)こう指定するのが正しいのではないのか、と。

そこで注目したのは、UIControlStateはOptionSetプロコトルを適用している事

OptionSetとは何者?

調べると「OptionSetとは、ビット列のフラグ管理を行う際に用いるプロコトルです。」とあります。つまり、normalやhighlighted、disabledという値は内部ではビット値なのね!という事が分かります。

そこで始めの疑問に戻るのですが、単純にビット値であれば、UIControlState()もビット値なのでは??と思いました。

さて続いて実験です。UIControlState()をログ出力してみよう。

print("UIControlState():\(UIControlState())")
print("UIControlState.normal:\(UIControlState.normal)")
print("UIControlState.highlighted:\(UIControlState.highlighted)")
print("UIControlState.disabled:\(UIControlState.disabled)")
print("UIControlState.selected:\(UIControlState.selected)")

UIControlState():UIControlState(rawValue: 0)
UIControlState.normal:UIControlState(rawValue: 0)
UIControlState.highlighted:UIControlState(rawValue: 1)
UIControlState.disabled:UIControlState(rawValue: 2)
UIControlState.selected:UIControlState(rawValue: 4)

おーっと!

UIControlState()もUIControlState.normalも0と出力されました。

という事は、

UIControlState()  ==  UIControlState.normal という事ですね。納得!

つまり、public init(rawValue: UInt)でビット値を指定しないと初期化で0になり、結果UIControlState.normalと同じ値になるって事ですね。

余談ですが、ビットフラグを管理しているという事は、もし3と入れたら、UIControlState.highlightedとUIControlState.disabledのフラグが立つのかと思ったのですが、できませんでした。どうやらビットの計算はしておらず、単純に合うビットの上げをしているようです。

以上です!

関連する記事

もっと見る