SwiftUI 文本字段可以与可选绑定一起使用吗?当前此代码:
struct SOTestView : View {
@State var test: String? = "Test"
var body: some View {
TextField($test)
}
}
产生以下错误:
无法转换“Binding”类型的值
有什么办法解决这个问题吗?在数据模型中使用选项是一种非常常见的模式——事实上,这是核心数据中的默认模式,所以SwiftUI不支持它们似乎很奇怪
确实,目前SwiftUI中的TextField
只能绑定到String
变量,而不是String?
。但您始终可以像这样定义自己的绑定
:
import SwiftUI
struct SOTest: View {
@State var text: String?
var textBinding: Binding<String> {
Binding<String>(
get: {
return self.text ?? ""
},
set: { newString in
self.text = newString
})
}
var body: some View {
TextField("Enter a string", text: textBinding)
}
}
基本上,您将文本字段
文本值绑定到此新绑定
最终API不允许这样做-但有一个非常简单且通用的解决方法:
extension Optional where Wrapped == String {
var _bound: String? {
get {
return self
}
set {
self = newValue
}
}
public var bound: String {
get {
return _bound ?? ""
}
set {
_bound = newValue.isEmpty ? nil : newValue
}
}
}
这允许您保留可选选项,同时使其与绑定兼容:
TextField($test.bound)
您可以添加这个运算符重载,然后它就像不是绑定一样自然地工作。
func ??<T>(lhs: Binding<Optional<T>>, rhs: T) -> Binding<T> {
Binding(
get: { lhs.wrappedValue ?? rhs },
set: { lhs.wrappedValue = $0 }
)
}
这将创建一个绑定,如果运算符值不是 nil,则返回该值的左侧,否则它将从右侧返回默认值。
设置时,它只设置lhs值,忽略与右侧有关的任何内容。
它可以这样使用:
TextField("", text: $test ?? "default value")