質問: true Toggle(isOn: $like){ Text("Like or Not").font(.largeTitle) } ```
回答: `@State`のようなアトリビュートは、Swift 5.1 (Xcode 11)で初めて導入されたもので、property wrapperと呼ばれます。 次の1行の宣言文は、 ``` @State var like = true ``` Swiftコンパイラ内部で次のような宣言に変換されてコンパイルされます。 ``` private var _like: State = State(wrappedValue: true) var like: Bool { get { return _like.wrappedValue } set { _like.wrappedValue = newValue } } var $like: Binding { get { return _like.projectedValue } } ``` (通常のプログラムからは`$like`のような`$`始まりの識別子を宣言することは出来ません。) このように`@State var like = true`と言う宣言は、`Bool`型の変数を宣言しているように見えて、実は`State`型の変数を宣言している訳です。 で、Swiftのproperty wrapperの場合、見かけのデータ型を包み込んでいる`State`のようなデータ型を便利に使うためのプロパティを1つだけ定義することができて、projection (投影)と呼ばれています。 つまり、 **`$like`はSwiftが自動生成した投影プロパティで、`like`の内側の`State`型を便利に使うためのもの** と言うことになります。 `State`と言うのは、SwiftUIにおいて状態変数を管理しやすくするためのデータ型である訳ですが、その投影データ型は`Binding`(今の場合、`Binding`)型になります。 渡している先の`Toggle`型のイニシャライザも`Binding`を受け取るものとして宣言されています。 `init(isOn: Binding, @ViewBuilder label: () -> Label)` この`Binding`と言うのは、働き的にはポインタか参照のようなもので、渡した時の値ではなく最新の値を取り出したり、値を変更したりすることができます。それで`Toggle`を操作した結果を元の`like`に反映することができる訳です。 SwiftUI絡みの機能については、Swift言語に関して公開されている情報以外に、Appleの独自拡張が含まれる場合もあるので、詳細まで突き詰めていくと上の説明とは若干整合性のない動作が見つかるかもしれませんが、通常の使い方をしている分にはこの説明で問題ないと思います。