1
2

More than 1 year has passed since last update.

【SwiftUI】@Bindingを初期化する時の注意点

Last updated at Posted at 2023-05-03

はじめに

前回privateな変数・定数が含まれるclassやstructをMemberwise Initializerで初期化しようとするとエラーが起きることを知りました。今回は、自分でinitを作成する際に@Binding変数がある場合の注意点です。

結論

@Binding変数を初期化する際はアンダースコア(_)を付ける

Cannot assign value of type 'Binding' to type 'String'

通常は@Binding変数を定義しても、Memberwise Initializerが自動で初期化してくれるので自分でinitializeを定義する必要はありません。しかし、private変数を使うなど自分でinitを書く必要がある場合、以下のような書き方をするとエラーが発生します。

struct ContentView: View {
    @State var text = "Hello"
    var body: some View {
        VStack {
            SecondView(text: $text)
        }
        .padding()
    }
}
struct SecondView: View {
    @Binding var text: String
    private var count = 0
    init(text: Binding<String>) {
        self.text = text // Cannot assign value of type 'Binding<String>' to type 'String'
    }
    var body: some View {
        VStack {
            Text(text)
        }
    }
}

エラーの内容は、「最初に定義したself.textString型なのに引数のtextBinding<String>型だからアクセスできません」といったものです。
https://qiita.com/crea/items/0b59722ab21e8c6cbb30
この記事ですごく分かりやすく解説されているのですが、

@Binding var text: String

は、実際は以下のような宣言として定義されています。

 var _text: Binding<String>
 var text: String {
     get {
         _text.wrappedValue
     }
     set {
         _text.wrappedValue = newValue
     }
 }

それぞれのクラスは表のようになります。

名前
_text Binding<String>
_text.wrappedValue String
text String

text自体は値を持たず、String型の_text.wrappedValugetメソッドで返すだけであり、Binding<String>型を表してるのは_textだと分かります。

解決策

self.textself._textもしくはただの_textと直します。

struct ContentView: View {
    @State var text = "Hello"
    var body: some View {
        VStack {
            SecondView(text: $text)
        }
        .padding()
    }
}
struct SecondView: View {
    @Binding var text: String
    private var count = 0
    init(text: Binding<String>) {
        self._text = text
    }
    var body: some View {
        VStack {
            Text(text)
        }
    }
}

終わりに

@BindingBinding<String>の関係がごっちゃになってました...

参考:
https://ja.stackoverflow.com/questions/63300/swiftの初期化処理でエラーが発生する/63305#63305
https://inon29.hateblo.jp/entry/2020/05/02/134257

1
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
1
2