前回までにユーザ操作に反応するオブジェクトとしてButtonやLinkを紹介しました。Appはユーザが触れることで状態を変化させていきますが、今のところ状態を保持する方法がありません。そこで今回は状態変化を保持するための 変数(var)@State を紹介します。

  • 前回のコードに続けて書く

  • 変数 var message をつくる

    • 変数: 独立して値を保持できる領域
    • messageの初期値は""(空文字)にする
  • messageの頭に @State をつける

    • 詳細は後述
  • Buttonを押したときの処理に message = “押しました” を追加

    • ボタンを押したときに、messageの内容が"“から"押しました"に変化する
  • TextオブジェクトをButtonの上に追加

    • Textの表示内容はmessage変数を設定する

いくつか新しい要素が出てきたので複雑に見えますが、イメージがつかめればシンプルです。まずはコードを書いて結果をみてみましょう。その後、結果の下にある「変数」と「@State」の説明へ進んでください。

コード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import SwiftUI

struct ContentView: View {
    @State var message:String = ""
    
    var body: some View {
        VStack {
            Text( message )
            .frame( width: .infinity, height: 50 )
            
            Button { 
                print( "押しました" )
                message = "押しました"
            }
            label: {
                Label( "アイコンを含むボタン", systemImage: "plus" )
                .foregroundStyle( .white )
                .padding( .vertical, 10 )
                .padding( .horizontal, 20 )
                .background( .blue )
                .clipShape( RoundedRectangle(cornerRadius: 8) )
            }

            Link( 
                "外部リンク",
                destination: URL( string:"https://wdkk.co.jp/" )!
            )
			.padding( 20 )
        }
    }
}

結果

swiftui_1_4_4_1.png

ボタンを押した後

swiftui_1_4_4_2.png

変数(var)

変数は、値を保持するメモリ領域を確保します。 Swiftでは var と書きます。

var message:String の意味は、messageが 変数名 、Stringが確保する領域の になります。変数をつくると message = “あ” のようにmessageの領域にStringの値を代入できるようになります。今回のコードでは”"(空文字)を入れています。

変数をつかうと、オブジェクトに直接値を書いていたところに変数を使うことができます。今回のコードですと Text( message ) がそれにあたります。

さて変数は名の通り値が変化するものですが、SwiftUIでは基本的に変数の値の変更が許されていません。ちょっと変な感じがしますがSwiftUIの仕組みによるものです。よって通常は1度保存した値を使いつづけることになります。

@State

しかし変数の値を1度決めたら変えられないのではAppの状態の変化を保持できず不便です。そこで @State を使います。変数に@Stateをつけると 変数の値が変更できるようになります

@Stateは Property Wrappers というAppの状態を管理するしくみです。SwiftUIには 「値が変わるところと不変のところを明確にして整理しましょう」 という考えがあり、値が変わるところにProperty Wrappersをつけるきまりになっています。

@Stateは少し面倒に感じますがメリットもあります。Property Wrappersをつけた変数はSwiftUIが管理してくれるため、値が変化したことを教えてくれます。これまでは値の変化を自分でチェックする必要がありましたので、@Stateを使うことでプログラムがまとめやすくなります。

(※Property Wrappersは@State以外の記述もありますが、ここでは割愛します)