SwiftUI(というかCombine?)についての記事を書こうと思っていたんですが、非常にややこしいことに気づいたので、基本要素を説明する記事を作りました。
State
おそらく、VStackとかHStackをわかった後にハマるのが、StateとかObservedかなと・・・
まずは、Stateから説明します。
@Stateとは?
変更が発生したときに、Viewを更新しなければいけない変数の属性です。
Viewに定義された場合は、この変数に変更があった場合に、body内のUIを、SwiftUIが再構築してくれます。
サンプル
想定される使用例:「+」「ー」のボタンがあって、このボタンによって、変数が増減されます。2つのボタンの間に、変数の値を表示しています。
このような場合は、ボタン操作で変数の値が変更されたときにあ、変数表示のビュー(この場合はText)を更新しないといけません。このような依存関係で使用するのが@Stateです。
変数定義に@Stateをつけて、変更があったことをきっかけとしてUIを更新(この場合は変数表示)させます。(SwiftUIにより更新されます)
struct ContentView: View { @State var count:Int = 0 var body: some View { HStack() { Button.init("-", action: { self.count = self.count - 1 }) Text.init("\(count)") Button.init("+", action: { self.count = self.count + 1 }) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
動作説明
+とーのButtonは、Pushされた時に、それぞれ、count変数を増減させます。(見たままです)
Textにも、count変数をそのまま渡しているので、セットされている数字が表示されます。初期値として0をセットしているので、立ち上げ直後は0が表示されてます。
ポイントは、”@State var count:Int = 0″です。特に、”@State”部分。この属性によって、このContentViewは、この属性が設定された変数(count)が変更されたときに、表示が更新されるようになります。具体的には、body変数が再評価されます。
UIKitで実現しようとすると?
以下のような実装が考えられます。
- ボタンを押されたときのコールバックで表示を更新する実装
- NotificationCenterを使って変更を監視して更新
- KVOを使って、変更を監視して、更新
- そのほかいろいろ・・・
いずれにしても、こんなに少ない行で実現することは難しいです。
まとめ
@Stateを設定することで、変更されたときにViewの更新が必要であることの宣言となっていて、実際、そのように更新されます。
なんとなく、動いてしまっているので、何がすごいの?という感じかもしれませんが、たった数文字の属性(@State)でここまで自動化されるのがすごいです。
学習コストもかかりますが、慣れてくると、少ない行で実現できていることで、可読性等も上がってくるはずで、良いことづくめです。
実際のアプリケーションで使うことを考えると、「別のビューに対しての更新はどうなの?」という質問が思い浮かぶと思います。次回はそのあたりを。
Sponsor Link