SwiftUI如何向子视图传递可变@FocusState并解决赋值报错问题
SwiftUI 子视图修改父视图传入FocusState报错解决方案
错误原因
- 子视图中声明的
isEditing是FocusState<Bool>.Binding类型,并非Bool值本身,直接给该类型变量赋值Bool值会触发类型不匹配错误 - SwiftUI的View结构体默认是不可变的,直接修改普通存储属性会触发
self is immutable错误,只有通过属性包装器修饰的属性、或修改Binding类型的wrappedValue才允许修改值
解决方案
方案1:保留现有声明,修改赋值逻辑
仅需将Button的点击事件赋值逻辑改为访问wrappedValue即可:
struct ChildView: View { @Binding var text: String var isEditing: FocusState<Bool>.Binding init(_ text: Binding<String>, _ isEditing: FocusState<Bool>.Binding) { self._text = text self.isEditing = isEditing } var body: some View { TextField("Username", text: $text) .focused(isEditing) Button("Click me!") { // 访问Binding包裹的真实值进行修改 isEditing.wrappedValue = false } } }
方案2:使用更符合SwiftUI惯例的@Binding声明
直接在子视图用@Binding修饰Bool类型即可,无需单独声明FocusState<Bool>.Binding类型,写法更统一。父视图不需要做任何修改,仍传入$isEditing(@FocusState的前缀$会自动生成Binding<Bool>类型),子视图修改为如下写法:
struct ChildView: View { @Binding var text: String // 直接用@Binding声明Bool类型即可 @Binding var isEditing: Bool init(_ text: Binding<String>, _ isEditing: Binding<Bool>) { self._text = text self._isEditing = isEditing } var body: some View { TextField("Username", text: $text) // 传入当前属性的Binding即可 .focused($isEditing) Button("Click me!") { // 直接赋值即可,不需要访问wrappedValue isEditing = false } } }
内容的提问来源于stack exchange,提问作者Kyle Horkley
相关产品推荐
相关产品推荐

