[SwiftUI] @Entry の使い方

SwiftUI2021

     
⌛️ 2 min.

@Entry を使って、簡単に Environment/ Transaction/ Container/ Focused Value を作って見ます。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS15.0.1 Sequoia
  • Xcode 16.1 Beta
  • iOS 18.1
  • Swift 5.9

@Entry

Xcode 15 以降では、@Entry マクロが 使えるようになりました。
このマクロは、Environment/ Transaction/ Container/ Focused への追加を容易にしてくれるマクロです。


参考
Entry()Apple Developer Documentation

MEMO

気にする人は少ないかもしれませんが 、Swift で @で始まる アトリビュート要素は複数あります。
Entry は、マクロとして実装されています。

The Swift Programming Language でのドキュメントは、こちら

なお、このマクロ自体は、iOS13/macOS10.15 まで遡って使えますが、対象となる要素がサポートされていないと 意味がありません。
例えば、FocusedValue は、iOS14/ macOS11 から導入されましたので それ以降でないと使用できません。

Environment の作り方

@Entryなしでの Environment の作り方

独自に Environment に追加するためには、@Entry なしで書くと以下のように書くことが必要でした。

struct MyOldColorEnvKey: EnvironmentKey {
    typealias Value = Color
    static var defaultValue: Color = .primary
}
extension EnvironmentValues {
    var myOldColor: Color {
        get { return self[MyOldColorEnvKey.self] }
        set { self[MyOldColorEnvKey.self] = newValue }
    }
}

上記のように定義することで、@Environment(.myOldColor) var oldColor として参照できるようになり、以下のように View の外部から 振る舞いを指定することができました。

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            MyOldColorView()
                .environment(\.myOldColor, .red)
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

struct MyOldColorView: View {
    @Environment(\.myOldColor) var oldColor
    var body: some View {
        Text("Hello, World! with myOldColor")
            .foregroundStyle(oldColor)
    }
}
myOldColor

外部から、environment 指定された色が使用されているのがわかります。

@Entry を使った Environment の作り方

独自の Environment の定義は非常に複雑というわけではありませんが、複数の Environment を定義し始めると ごちゃごちゃ してしまいがちでした。

@Entry を使うと、以下のようにすっきりと記述することができます。EnvironmentKey を定義することなく、EnvironmentValues の extension のみで 定義できます。

extension EnvironmentValues {
    @Entry var myColor: Color = .primary
}

拍子抜けするくらい短いです。

ちなみに、マクロを展開してみると以下のようになっていることが確認でき、以前に書いていた EnvironmentKey もマクロによる展開で 定義されていることがわかります。

extension EnvironmentValues {
    @Entry var myColor: Color = .primary
    {
        get {
            self[__Key_myColor.self]
        }
        set {
            self[__Key_myColor.self] = newValue
        }
    }
    private struct __Key_myColor: SwiftUICore.EnvironmentKey {
        typealias Value = Color
        static var defaultValue: Value { .primary }
    }
}

先ほどのビューに 新規 Environment を参照する要素を追加してみました。

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            MyColorView()
                .environment(\.myColor, .green)
            MyColorView()
                .environment(\.myColor, .blue)
            MyOldColorView()
                .environment(\.myOldColor, .red)
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

struct MyColorView: View {
    @Environment(\.myColor) var color
    var body: some View {
        Text("Hello, World! with myColor")
            .foregroundStyle(color)
    }
}

struct MyOldColorView: View {
    @Environment(\.myOldColor) var oldColor
    var body: some View {
        Text("Hello, World! with myOldColor")
            .foregroundStyle(oldColor)
    }
}

extension EnvironmentValues {
    @Entry var myColor: Color = .primary
}

struct MyOldColorEnvKey: EnvironmentKey {
    typealias Value = Color
    static var defaultValue: Color = .primary
}
extension EnvironmentValues {
    var myOldColor: Color {
        get { return self[MyOldColorEnvKey.self] }
        set { self[MyOldColorEnvKey.self] = newValue }
    }
}
myColor

当然ですが、どちらも動作しますし、共存できます。

@Entry が有効な型

ドキュメントにも書かれていますが、@Entry は 以下の定義に有効です。
・Environment
・Transaction
・Container
・Focused

まとめ

@Entry を使うと、容易に Environment/ Transaction/ Container/ Focused を定義できる

@Entry の使い所
  • Environment/ Transaction/ Container/ Focused を定義するのに使用できる
  • “@Entry var name: Int = 0” のように非常に容易に定義できる。

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です