見出し画像

[SwiftUI]@Stateと@Bindingの関係性について

こんばんは。なかがわ(Twitter)です。
今回は、先日書いた@Stateとセットで使われる
@Bindingについて、書いていきたいと思います。

@Stateを付与されたプロパティはSwiftUIの監視下に置かれ、
プロパティ内部に更新があるたびにそれを検知し、
Viewを自動更新するという特徴がありました。
では、@Bindingはどういう振る舞いをするか。見て行きます。
では、よろしくお願いします。

@Bindingって??


@Bindingをつけることで、View間での双方向のデータ共有
可能になります。

自らは値を保有せずに、親のプロパティへの参照を表します。
これにより、子View内でのプロパティ更新は、
親のプロパティに反映(=Viewにも反映)されます。

同様の方法で、子Viewのさらに子Viewへと親プロパティの参照値を
受け継げます。

異なるView間でデータのやり取りができるとありますね。
サンプルコードと、実機の動きを見てみましょう。
今回はメイン画面とサブ画面の2種類のViewを作り、
2つのView間でBool値のデータ共有をし、Bool値の変化によって
wi-fiシンボル画像をif文で分岐させてみました。

// ①Wifiの状態が表示されるメイン画面「 WifiView 」
struct WifiView: View {
    
    @State var isPowerToggle = false    // Wifi画像を切り替えるBool型の値 初期値false
    
    var body: some View {
        
        
        NavigationView{
            
            VStack {
                
                // ON,OFFでWifi画像を切り替える条件分岐
                if isPowerToggle == true {
                    
                    Image(systemName: "wifi")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 200, height: 200)
                    
                } else {
                    
                    Image(systemName: "wifi.slash")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 200, height: 200)
                    
                }
                
                // SetUpViewへ遷移する
                // SetUpViewにisPowerToggleをバインド
                NavigationLink(destination: SetUpView(isPowerToggle: $isPowerToggle)) {
                    
                    Text("wifi設定→")
                        .font(.title)
                        .frame(width: 200, height: 50)
                    
                }

                
            } // VStack
        } // NavigationView
    }// body
}// View



// ②電源のON,OFFを操作するサブ画面「SetUpView」
struct SetUpView: View {
    
    @Binding var isPowerToggle: Bool    // 親ViewでState宣言した値を子Viewと共有
    
    var body: some View {
        
        VStack {
            
            // ONボタン
            Button(action: {
                isPowerToggle = true    // ボタンタップで電源ON
            }) {
                Text("ON")
                    .font(.title)
                    .frame(width: 200, height: 50)
            }
            
            // OFFボタン
            Button(action: {
                isPowerToggle = false   // ボタンタップで電源OFF
            }) {
                Text("OFF")
                    .font(.title)
                    .frame(width: 200, height: 50)

            } 
        }// VStack
    } // body
} // View

実機の動きはこちら↓

小さくてすみません…


①「WifiView」

今回のメイン画面、親Viewとなります。
@Stateを付与したBool型変数「isPowerToggle」を宣言し、
値が変化することでViewが更新され、
Wifiシンボル画像表示がif文によって分岐変化されます。

親View①「WifiView」

②「SetUpView」

今回のサブ画面、子Viewとなります。
NavigationLinkを用いてメイン画面から遷移させています。

ONをタップ ⇨   isPowerToggle = true
OFFをタップ ⇨  isPowerToggle = false

@Bindingを付与した「isPowerOn」を子View内に宣言することで
メイン画面の@Stateプロパティと状態を同期させています。
ONをタップすることで、trueがメイン画面の@Stateに
引き渡され、値が変化することでViewが更新されます。
@Bindingでの宣言時、初期値は入れずに宣言します。
(補)@Bindingでの宣言時、初期値は入れずに宣言します。

子View②「SetUpView」


まとめ


@State、@Bindingの関係性についてでした。
今回はBool型のデータバインディングを行いましたが、
String型やInt型など他の型もバインディングすることができます。
データバインディングについて、これからも調べて行きたいと
思います。ではでは。

以上


この記事が気に入ったらサポートをしてみませんか?