SwiftUI文本字段可以与可选绑定一起使用吗?当前此代码:
struct SOTestView : View {
@State var test: String? = "Test"
var body: some View {
TextField($test)
}
}
产生以下错误:
无法将类型'Binding
'的值转换为预期的参数类型'Binding '
有什么办法解决吗?在数据模型中使用Optionals是一种非常常见的模式-实际上,这是Core Data中的默认设置,因此SwiftUI不支持它们似乎很奇怪
答案 0 :(得分:25)
您可以添加此运算符重载,然后它像不是绑定一样自然工作。
func ??<T>(lhs: Binding<Optional<T>>, rhs: T) -> Binding<T> {
Binding(
get: { lhs.wrappedValue ?? rhs },
set: { lhs.wrappedValue = $0 }
)
}
这将创建一个Binding,如果它不为nil,则返回操作符值的左侧,否则它将从右侧返回默认值。
设置时仅设置lhs值,而忽略与右侧有关的任何事情。
可以这样使用:
TextField("", text: $test ?? "default value")
答案 1 :(得分:5)
是的,目前SwiftUI中的TextField
只能绑定到String
变量,不能绑定到String?
。
但是您总是可以这样定义自己的Binding
:
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)
}
}
基本上,您将TextField
文本值绑定到此新的Binding<String>
绑定,绑定将其重定向到您的String?
@State变量。
答案 2 :(得分:1)
您可以尝试
struct SOTestView : View {
@State var test: String? = "Test"
var body: some View {
test.map {
TextField($0)
}
}
}
答案 3 :(得分:0)
对于结束,正如@kontiki在注释中指出的那样,这是不可能的,因为TextField需要Binding
有关如何执行此操作的问题,请参见以下问题:How to Use BindingConvertible in SwiftUI?
答案 4 :(得分:0)
尝试一下:
struct ContentView : View {
@Binding var test: String
var body: some View {
TextField("Test",text: self.$test)
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView(test: .constant(""))
}
}
#endif
答案 5 :(得分:0)
一个可能的解决方案是创建一个自定义扩展:
extension Binding {
func unwrapped<Wrapped>(
defaultValue: Wrapped
) -> Binding<Wrapped> where Value == Wrapped? {
.init(
get: { wrappedValue ?? defaultValue },
set: { wrappedValue = $0 }
)
}
}
并像这样使用它:
TextField("", text: $test.unwrapped(defaultValue: "text"))