最近在工作中设置TextField的focus事件时,碰到一个错误
“Cannot convert value of type 'Binding<Bool>' to expected argument type 'FocusState<Bool>.Binding'”
这个错误的原因是.focused(_:) 修饰符需要的是 @FocusState 生成的绑定(FocusState.Binding),而不是普通的 @State 生成的 Binding那么focusState 相比State有什么特殊之处呢?我们先来看看focusState的使用:
struct ContentView: View {
@State private var text = ""
@FocusState private var isFocused: Bool
var body: some View {
VStack {
TextField("输入", text: $text)
.focused($isFocused)
// 可以通过按钮控制焦点
Button("聚焦") {
isFocused = true
}
// 可以通过按钮清空文本
Button("清空") {
text = ""
}
}
}
}
这种使用很简单,同@State基本相同,接下来我们来看下多个输入框的情况
struct ContentView: View {
@State private var text1 = ""
@State private var text2 = ""
// 使用枚举管理多个输入框的焦点
enum Field: Hashable {
case text1
case text2
}
@FocusState private var focusedField: Field?
var body: some View {
VStack {
TextField("输入1", text: $text1)
.focused($focusedField, equals: .text1)
TextField("输入2", text: $text2)
.focused($focusedField, equals: .text2)
Button("聚焦到输入框1") {
focusedField = .text1
}
Button("聚焦到输入框2") {
focusedField = .text2
}
}
}
}
这个同官方注释中的例子基本是相同的,官方的例子更容易体现在我们平时的开发中
FocusState不仅适用于布尔值,还适用于任何Hashable类型。这意味着我们可以使用符合Hashable协议的枚举类型
对聚焦状态进行建模。我们应该将FocusState属性设为可选,以便与Hashable枚举结合使用,因为目前可能没有聚焦视图。