@State private var の場合
例えば、テキストを編集するための View について考えてみましょう。
- 前画面から既存の文字列を受け取り、 TextField の初期値として表示する
- 表示された文字列を修正することができる
このような仕様の場合、 1 は以下のようなコードで実現できます。
struct TextEditView: View {
@State private var text: String
init(text currentText: String) {
_text = State(initialValue: currentText)
}
var body: some View {
TextField("", text: $text)
}
...
}
let currentText = "Today was a good day."
TextEditView(text: currentText)
あれ?こっちは??
struct TextEditView: View {
@State private var text: String
init(text currentText: String) {
text = currentText // ❗️ Return from initializer without initializing all stored properties
}
...
}
初期化が完了していないというエラーが出ます。text に代入してるのに。。
実は初期化する必要があるのは、
文字列
ではなく 文字列の状態
String
ではなく State<String>
text
ではなく _text
1
です。 text の 初期状態 をセットしてあげる必要があります。
(初期値ではなく、初期状態と表現する方が適切かと思います。)
今回の例では currentText: String
を State
でラップし 状態 として代入しています。
_text = State(initialValue: currentText)
@State var の場合
こちらは素直にコンパイルが通ります。
struct TextEditView: View {
@State var text: String
...
}
let currentText = "Today was a good day."
TextEditView(text: currentText)
イニシャライザが内部でうまく処理してくれてるのかな。
-
_ (アンダースコア) を付けることで Property Wrapper 自身にアクセスできる。 ↩