FocusState又是何方神圣

192 阅读1分钟

最近在工作中设置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 ContentViewView {    
@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 ContentViewView {    
    @State private var text1 = ""    
    @State private var text2 = ""
    // 使用枚举管理多个输入框的焦点    
    enum Field: Hashable {        
    case text1        
    case text2    
    }

    @FocusState private var focusedFieldField?
    var bodysome 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枚举结合使用,因为目前可能没有聚焦视图。