大家好
我有一个父视图,其中包含多个子视图,其中包含多个文本字段。
我想向键盘工具栏添加 V 形以轻松将焦点移动到下一个 TextField,但我不知道如何访问子视图的 FocusState。
是否有办法获取与焦点标识符对应的视图(?,不知道该怎么称呼它)?
struct ParentView: View {
@FocusState var focusedChild: Int?
var body: some View {
ForEach(1..<5) { index in
ChildView(index: index)
.focused($focusedChild, equals: index)
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Button {
// focusPrevious() <--
// Is there a way to access the view associated with the index or the current focusedChild?
// ChildView[index].focusState = ChildView[index].focusState + 1 % 3
} label: {
Image(systemName: "chevron.left")
}
Button {
//
} label: {
Image(systemName: "chevron.right")
}
Spacer()
Button {
focusedChild = nil
} label: {
Image(systemName: "keyboard.chevron.compact.down")
}
}
}
}
}
struct ChildView: View {
var index: Int
@State var field1: String = ""
@State var field2: String = ""
@State var field3: String = ""
@FocusState var focusedField: Int?
var body: some View {
VStack {
Text(String(index))
TextField("Field 1", text: $field1)
.focused($focusedField, equals: 1)
TextField("Field 2", text: $field2)
.focused($focusedField, equals: 2)
TextField("Field 3", text: $field3)
.focused($focusedField, equals: 3)
}
}
}
我尝试将工具栏添加到 ChildView,但这会导致每个 childView 都有一对 V 形图案(在本例中为 3 对 V 形图案),而不是只有一对。
任何帮助将不胜感激,谢谢!
由于子视图已经采用了
index
,因此只需根据它分配不同的焦点状态即可。如果您以连续数字的方式执行此操作,“转到下一个/上一个文本字段”将是微不足道的。您可以将它们指定为 index * 3
、index * 3 + 1
和 index * 3 + 2
。
子视图不应在每个子视图中具有
FocusState
,而应采用 FocusState<Int?>.Binding
(与常规 Binding
类似,但用于焦点状态)。
struct ChildView: View {
let index: Int
@State var field1: String = ""
@State var field2: String = ""
@State var field3: String = ""
let focusedField: FocusState<Int?>.Binding
var body: some View {
VStack {
Text(String(index))
TextField("Field 1", text: $field1)
.focused(focusedField, equals: index * 3)
TextField("Field 2", text: $field2)
.focused(focusedField, equals: index * 3 + 1)
TextField("Field 3", text: $field3)
.focused(focusedField, equals: index * 3 + 2)
}
}
}
为了更灵活的方法,
ChildView
可以只获取所有三个文本字段的焦点状态,例如
let textField1Focus: Int
let textField2Focus: Int
let textField3Focus: Int
无论如何,现在您应该删除
.focused
s 上的 ChildView
修饰符:
ForEach(0..<4) { index in
ChildView(index: index, focusedField: $focusedChild)
}
那么前进和后退按钮就是:
Button {
if let focusedChild, focusedChild > 0 {
// be careful here, self.focusedChild and focusedChild are not the same thing!
// focusedChild is the unwrapped value!
self.focusedChild? -= 1
}
} label: {
Image(systemName: "chevron.left")
}
Button {
if let focusedChild, focusedChild < 11 {
self.focusedChild? += 1
}
} label: {
Image(systemName: "chevron.right")
}