Swift @FocusStateが子ビューでうまく機能しない
解決したいこと
子ビューでフォーカスを制御したいのですが、うまくいきません。
二つのテキストフィールドのうち、一つ目のテキストフィールドの入力が終わりユーザーが改行を押した時に
二つ目のテキストフィールドに自動的にフォーカスされるようにしたいです。
具体的には、focusedモディファイアのところに以下のようなエラーメッセージが出ます。
発生している問題・エラー
Accessing FocusState's value outside of the body of a View. This will result in a constant Binding of the initial value and will not update.
該当するソースコード(親ビュー)
struct ContentView: View {
@State var selectedTab: Int = 0
var body: some View {
TabView(selection: $selectedTab) {
HomeTabView()
.tabItem({
Image(systemName: "house")
Text("Home")
})
ReminderTabView()
.tabItem {
Image(systemName: "checklist")
Text("Reminder")
}.tag(1)
SettingTabView()
.tabItem({
Image(systemName: "gear")
Text("Setting")
}).tag(2)
}
}
}
該当するソースコード(子ビュー)
struct HomeTabView: View {
@StateObject var textField_What = MyTextField()
@StateObject var textField_When = MyTextField()
var body: some View {
VStack(alignment: .leading) {
Text("何を?").padding(.leading)
TextField("テキストフィールド",
text: $textField_What.content,
onEditingChanged: { begin in
if begin {
self.textField_What.isEditting = true
} else {
self.textField_What.isEditting = false
}
},
onCommit: {
textField_When.isFocused = true
})
.focused(textField_What.$isFocused) // エラーが表示されます。
.textFieldStyle(.roundedBorder)
.padding(.horizontal)
.shadow(color: textField_What.isEditting ? .blue : .clear, radius: 3)
Text("いつ?").padding([.leading, .top])
TextField("テキストフィールド",
text: $textField_When.content,
onEditingChanged: { begin in
if begin {
self.textField_When.isEditting = true
} else {
self.textField_When.isEditting = false
}
})
.focused(textField_When.$isFocused) // エラーが表示されます。
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.horizontal)
.shadow(color: textField_When.isEditting ? .blue : .clear, radius: 3)
}
}
}
class MyTextField: ObservableObject {
@Published var content = ""
@Published var isEditting = false
@FocusState var isFocused
}
構成自体は間違っていないと思うので、必要な部分だけを別のプロジェクトで作ってみたのですが、そちらはうまくいきました。
上手くいったソースコード(親ビュー)
struct ContentView: View {
var body: some View {
SubView()
}
}
上手くいったソースコード(子ビュー)
struct SubView: View {
@State private var string1 = ""
@State private var isEditting1 = false
@FocusState var isFocused1
@State private var string2 = ""
@State private var isEditting2 = false
@FocusState var isFocused2
var body: some View {
VStack {
Text("改行で次へ").bold().font(.title2)
TextField("aaa", text: $string1,
onCommit: {
isFocused2 = true
})
.padding()
.textFieldStyle(.roundedBorder)
.focused($isFocused1)
TextField("bbb", text: $string2)
.padding()
.textFieldStyle(.roundedBorder)
.focused($isFocused2)
}
}
}
やっていることは、先ほどのものと変わらず、テキストフィールドで値が送信されたときに@FocuesStateがついたプロパティを切り替えています。
0