[SwiftUI] Stateful な Button を作る

SwiftUI

SwiftUI の Button は、ステート(状態)をもちません。ケースによっては、状態を保持して、表示等を切り替えてくれると便利なので、そのような Button を作ってみます。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.3
  • Xcode 12.5
  • iOS 14.5

Stateful な Button

状態を持たせたいので、内部に Bool を持つような Button とします。

内部の Bool の状態に応じて表示する Label を切り替えるようにします。

また、内部の Bool の状態を取得したい時があるので、ボタンが押された時に、(変更後の Bool を引数に) 指定 closure が呼ばれるように作ります。

要件

つまり、以下が要件になります。

  • Bool を内部で保持する
  • Bool の値に応じて、異なるラベルを表示する
  • Bool の値が変更された際には、指定した closure 経由で変更後の値が取得できる

1つづつ 順番に実装していきます。

Bool を保持する View を定義

名前は、SDSStatefulButton としています。

内部に Bool を保持する Button を表示する View を定義します。

コード解説
  1. Bool を @State な変数として定義します
  2. 外部から初期値を指定できるようにしています
  3. Button を表示しています。bValue の値に応じて Button のラベルの Text を変更しています。

以下のような ContentView で動作を確認してみます。

以下のような動作になります。

true / false でラベルが切り替わる Button

Button の定義と同じように、表示に使う View を外部から 渡せるようにします。内部の Bool 値に応じて、異なる View を表示できるように、2つの View を設定できるようにします。

コード解説
  1. Generics を使用して、On/Off 用の View を指定します。
  2. 渡された View を内部に保持します
  3. bValue の値に応じて、適切なビューを表示します

ボタンを使う側は以下のように書くことができます。

コード解説
  1. true 時に表示される Label (View) を外部から指定します
  2. false 時に表示される Label (View) を外部から指定します

以下のような動作になります。

ここまでで、3つの要件のうちの最初の2つを満たせました。

値変更時に closure を呼び出す

初期化時に渡された closure を呼び出すだけです。

ボタンを使う側は以下のように書くことができます。

以下のような動作になります。

これで、内部に Bool を保持し、値によって 表示を変更し、値変更時にはclosure が呼ばれる Button を作ることができました。

まとめ:Stateful な Button の作り方

Stateful な Button の作り方
  • 変数は、@State で保持し、変更に応じてビューが更新されるようにする
  • Generics を使って、さまざまな View を Label に使用できるようにする
  • 外部から closure を渡せるようにして、値変更時には、closure を呼ぶ

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

# SwiftUI2.0 が登場したことで少し古くなってしまいましたが、いまでも 定番本です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です