【SwiftUI】@Stateの使い方

SwiftUIのデータバインディングの仕組みの一つである、@Stateについて解説します。

スポンサーリンク

環境

この記事の情報は次のバージョンで動作確認しています。

【Xcode】11.2.1
【Swift】5.1
【iOS】13.2.2
【macOS】Catalina バージョン 10.15.2

@Stateの概要

@Stateはプロパティの宣言時に使えるSwiftUIのカスタム属性です。
プロパティの値とUIの状態を自動的に同期する仕組みを実現します。

@Stateをつけたプロパティには次の2つの機能が付加されます。

  1. 値が更新可能になる。
    SwiftUIのViewはStructの為、通常ではプロパティを更新する事ができませんが、@Stateを付ける事で更新できるようになります。
  2. 値の変更がSwiftUIよってモニタリングされる。
    モニタリングしたプロパティに変更があった場合、対象プロパティを参照しているViewが自動的に再描画されます。これにより、プロパティの値とUIの状態の同期が実現されます。

サンプルソース

isPowerOnプロパティが@Stateで宣言されており、電源ボタンのクリックで値のtrue/falseが切り替わります。
isPowerOnプロパティが更新されると、それに合わせてテキストが自動的に再描画されます。

【図1:サンプル】

@State使用時の注意点

@Stateで宣言されたプロパティはそれを保持するViewとその子Viewからしかアクセスできません。この為、private修飾子をつける事をAppleでは推奨しています。

外から値を設定する事はできない為、プロパティは初期値が必要になります。
View内のみで使うデータフローを扱う事に適している仕組みです。

子Viewに値を渡す

先程のサンプルソースの電源ボタンの部分をカスタムView化して分割した例を示します。

@Stateで宣言されたプロパティを子Viewに渡す時は、プロパティ名の頭に$を付けます。
プロパティの値そのものではなく、プロパティへの参照を渡すイメージです。

子View側では、@Stateではなく@Bindingでプロパティを宣言します。
自らは保有せずに、親のプロパティを参照する事を示します。
これにより、子View内でのプロパティ更新は、親のプロパティに反映されます。

標準部品に値を渡す

ToggleやTextFieldのような標準部品でも、この仕組みを利用しています。

例えば、以下はToggleのイニシャライザです。

引数isOnの型がBinding<Bool>になっているのがわかります。
先程のサンプルの子View呼び出しの部分を次のコードに置き換えるだけで、電源ボタンの代わりにToggleボタンが使用できます。

【図2:Toggleに置き換え】

SwiftUI
スポンサーリンク
スポンサーリンク
カピ通信

コメント