SwiftUIのデータフローとバインディング:基本から応用まで

この記事は約5分で読めます。

この記事では、SwiftUIにおけるデータフローの理解とバインディングの活用方法について、基本から応用まで詳しく解説します。

SwiftUIのデータフロー

SwiftUIのデータフローは、アプリケーションの状態とUIの間の相互作用を管理するための概念です。
主に以下のプロパティラッパーを使用して、データの流れを制御します。

@State

  • 説明: ビューの内部で管理されるプライベートな状態を定義します。
  • 用途: 単一のビュー内でのみ必要なデータや状態の管理。

@Binding

  • 説明: 親ビューと子ビュー間で状態を共有するためのプロパティラッパーです。
  • 用途: 親ビューの@State変数を子ビューに渡して、共有した状態を更新します。

@ObservedObject / @StateObject

  • 説明: ビューの外部で管理されるオブジェクトに対する参照を提供します。@StateObjectはビュー内で生成されるオブジェクトに使用され、@ObservedObjectは外部から渡されるオブジェクトに使用されます。
  • 用途: 複数のビュー間で共有される複雑なデータモデルや状態の管理。

@EnvironmentObject

  • 説明: アプリケーション全体で共有されるデータへのアクセスを提供します。
  • 用途: アプリ全体の設定やユーザーデータなど、多くのビューで共有されるデータ。

データバインディングの流れ

親ビューの動作

電球のスイッチに@Stateを付与したisLigthBulbプロパティを紐づけています。スイッチのOn/Offを切り替えることでisLigthBulbの値も変化します。

isLightbulb→Falseの時
isLightbulb→Trueの時
import SwiftUI

struct BindingFlowSmp: View {
    @State private var isLightbulb = true
    var body: some View {
        Toggle("電球", isOn: $isLightbulb)
            .padding()
    }
}

子ビューの動作

@Bindingを付与したプロパティの状態によって表示する画像を切り替えています。

lightbulb→Falseの時
lightbulb→Trueの時
struct ChildBindingFlowSmp: View {
    @Binding var lightbulb: Bool
    var body: some View {
        if lightbulb {
            Image(systemName: "sun.max")
                .resizable()
                .frame(width: 100, height: 100)
        }
        else {
            Image(systemName: "sun.min")
                .resizable()
                .frame(width: 100, height: 100)
        }
    }
}

親ビューと子ビューの組み合わせ

親ビューと子ビューを組み合わせると以下のようなビューとなります。

ポイントは子ビューで@Bindingプロパティであるlightbulに親ビューのisLightbulbを紐づけています。

import SwiftUI

struct BindingFlowSmp: View {
    @State private var isLightbulb = true
    var body: some View {
        Toggle("電球", isOn: $isLightbulb)
            .padding()
        ChildBindingFlowSmp(lightbulb: $isLightbulb)
    }
}

struct ChildBindingFlowSmp: View {
    @Binding var lightbulb: Bool
    var body: some View {
        if lightbulb {
            Image(systemName: "sun.max")
                .resizable()
                .frame(width: 100, height: 100)
        }
        else {
            Image(systemName: "sun.min")
                .resizable()
                .frame(width: 100, height: 100)
        }
    }
}

こうすることで@Stateプロパティが更新されると、その変更が@Bindingを介して関連するビューに伝播します。

まとめ

SwiftUIのデータフローとバインディング機能は、アプリの状態管理とUIの相互作用をシンプルで効果的にします。@State、@Binding、@ObservedObject、@EnvironmentObjectといったプロパティラッパーを適切に使用することで、クリーンでメンテナンスしやすいコードを実現できます。

タイトルとURLをコピーしました