3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

@Environmentについて、そろそろ"きちんと"理解したいあなたへ

Last updated at Posted at 2024-12-07

こんにちは。takasan1234と申します。本記事では、SwiftUI開発で頻繁に目にする@Environmentについて、より深く理解することを目的に解説します。これまで他の記事で見かけるたびになんとなく使っていた方も多いと思います。今日こそしっかりと理解して、エンジニアとしてスキルアップしていきましょう。

本記事で得られる情報

@Environmentとは
・SwiftUIが用意している@Environmentプロパティ
・カスタム@Environmentとは

各ツールのバージョン

使用したツールのバージョンは以下のとおりです

Xcode Version 16.1

@￰Environmentとは

@Environmentは、データを格納できる棚のような仕組みです。@Environmentさまざまな画面からデータの一時保持、アクセス、管理が可能です(ただし、永続的な保存はできません)。これは、アプリ全体で共有される設定や状態の管理に特に役立ちます。自分で用意したデータを管理できるだけでなく、SwiftUIが予め用意したデータも利用できます(詳細は後述)。後者を使えば、デバイスの情報や現在の日時などの便利な情報を簡単に取得できます。

スクリーンショット 2024-12-06 17.47.56.png

Reactの経験がある方は、「Contextに似ている」と理解しやすいでしょう。

@￰Environmentの種類

@Environmentには大きく分けて2種類あります。

・SwiftUIが用意している@Environment
・自作の@Environment

以下では、これら2種類の@Environmentについて詳しく解説していきます。

SwiftUIが用意している@￰Environment

SwiftUIで@Environmentを実際に使う例見てみましょう。
以下は、アプリのカラー・スキーム(ダークモードまたはライトモード)の状態を取得する基本的な例です。

struct ContentView: View {
    // 現在のカラー・スキームを取得
    @Environment(\.colorScheme) var colorScheme: ColorScheme

    var body: some View {
        // カラー・スキームによって異なるテキストを表示
        Text(colorScheme == .dark ? "ダークモード" : "ライトモード")
            .padding()
    }
}

この行での中で特に重要なのが3行目です。

// 3行目のコード
@Environment(\.colorScheme) var colorScheme: ColorScheme

この行で、@Environmentの棚の一つであるcolorSchemeの中から値を取り出しています。

スクリーンショット 2024-12-06 17.59.05.png

@Environmentの値にアクセスする方法(一般形)

@Environment(\.<環境キー>) var <環境変数名>: <>

環境キー名 一覧

colorSchemeの他にも、SwiftUIには多くの便利な環境地が用意されています。

環境キー 説明 取り得る値
colorScheme アプリのテーマカラー設定 ColorScheme .light(明るい), .dark(暗い)
locale ユーザーの地域・言語設定 Locale en_US, ja_JP など
presentationMode ビューの表示状態 Binding .presented, .dismissed
horizontalSizeClass 画面の横幅に基づくレイアウト UserInterfaceSizeClass .compact(狭い), .regular(広い)
verticalSizeClass 画面の高さに基づくレイアウト UserInterfaceSizeClass .compact(短い), .regular(長い)
accessibilityEnabled アクセシビリティの状態 Bool true(有効), false(無効)
font フォントの設定 Font .body, .title など
dynamicTypeSize 文字サイズの設定 DynamicTypeSize .small から .extraExtraExtraLarge
scenePhase アプリの実行状態 ScenePhase .active(実行中), .inactive(一時停止), .background(背景)
openURL URLを開く機能 OpenURLAction URLを開くアクション

自作の@￰Environment

次に独自のデータを@Environmentとして利用する方法を見ていきましょう。以下のサンプルプログラムは、アプリ内で整数カウンターを共有する仕組みを実装したものです。まずは全体像を把握するため、軽く目を通してください。詳細は後ほど解説します。

// コード1
extension EnvironmentValues {
    @Entry var count: Int = 0
}

// コード2
struct ContentView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            ChildView()
            Button("Increment") {
                count += 1
            }
        }
        .environment(\.count, count)
    }
}

struct ChildView: View {
    var body: some View {
        CountView()
    }
}

//コード3
struct CountView: View {
    @Environment(\.count) var count: Int

    var body: some View {
        Text("\(count)")
    }
}

上記のコードを参考に、カスタム@Environmentの使用方法を3つのステップで解説します。
・領域の確保
・値の更新
・値の取得

スクリーンショット 2024-12-07 12.44.45.png

領域の確保

@Environment自分のデータを格納するスペースを確保する方法について解説します。データを保存するには、まずそのためのスペースを確保する必要がありますよね。

コード1
extension EnvironmentValues {
    @Entry var count: Int = 0
}

このコード1では、@Environmentを使用してcountの保存領域を確保します。図の青い矢印が示すのが、この処理です。

EnvironmentValuesは@Environmentで使用する値を定義する構造体です。SwiftUIはこの中にcolorSchemeやlocaleなどの値をあらかじめ登録しています。コード1ではEnvironmentValuesを拡張して、独自のcountプロパティを追加しています。

スクリーンショット 2024-12-06 18.25.48.png

@￰Environmentへの登録方法(一般形)

extension EnvironmentValues {
    @Entry var <プロパティ名>: <データ型> = <初期値>
}

値の更新

コード2
struct ContentView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            ChildView()
            Button("Increment") {
                count += 1
            }
        }
        .environment(\.count, count)
    }
}

.environment(\.count, count)は親ビューのcount変数を環境変数として子ビューに渡します。これにより、子ビューからcountの最新の値にアクセスできます。

スクリーンショット 2024-12-07 12.34.01.png

値の更新方法(一般形)

.environment(\.<環境キー>, <>)

値の取得

先ほどのSwiftUI標準の@￰Environmentと同様に、以下の方法で値を取得できます。

コード3
struct CountView: View {
    @Environment(\.count) var count: Int

    var body: some View {
        Text("\(count)")
    }
}

スクリーンショット 2024-12-07 12.45.54.png

@Environmentの値にアクセスする方法(一般形)

@Environment(\.<環境キー>) var <環境変数名>: <>

まとめ

SwiftUIが用意している@￰Environmentの利用

@Environmentの値にアクセスする方法(一般形)

@Environment(\.<環境キー>) var <環境変数名>: <>

カスタム@￰Environmentの利用

@￰Environmentへの登録方法(一般形)

extension EnvironmentValues {
    @Entry var <プロパティ名>: <データ型> = <初期値>
}

値の更新方法(一般形)

.environment(\.<環境キー>, <>)

@Environmentの値にアクセスする方法(一般形)

@Environment(\.<環境キー>) var <環境変数名>: <>

最後に

少しでも参考になれば幸いです。
最後までお読み頂きありがとうございました!!

参考記事

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?