SwiftUI可选文本字段

SwiftUI可选文本字段,swiftui,Swiftui,SwiftUI文本字段可以与可选绑定一起使用吗?目前,该代码: struct SOTestView : View { @State var test: String? = "Test" var body: some View { TextField($test) } } 产生以下错误: 无法将“Binding”类型的值转换为预期的参数类型“Binding” 这有什么办法吗?在数据模型中使用Optionals是一种非常常见的模式-事实上,这是核心数据中的

SwiftUI文本字段可以与可选绑定一起使用吗?目前,该代码:

struct SOTestView : View {
    @State var test: String? = "Test"

    var body: some View {
        TextField($test)
    }
}
产生以下错误:

无法将“Binding”类型的值转换为预期的参数类型“Binding


这有什么办法吗?在数据模型中使用Optionals是一种非常常见的模式-事实上,这是核心数据中的默认设置,因此SwiftUI不支持Optionals似乎很奇怪

最终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)

是的,目前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)
    }
}
导入快捷界面
结构测试:视图{
@状态变量文本:字符串?
var textBinding:Binding{
装订(
获取:{
返回self.text??“”
},
集合:{newString in
self.text=newString
})
}
var body:一些观点{
TextField(“输入字符串”,text:textBinding)
}
}

基本上,您可以将
TextField
文本值绑定到这个新的
绑定
绑定,绑定会将它重定向到您的
字符串?
@状态变量。

您可以添加这个操作符重载,然后它就像不是绑定一样自然工作

func ??<T>(lhs: Binding<Optional<T>>, rhs: T) -> Binding<T> {
    Binding(
        get: { lhs.wrappedValue ?? rhs },
        set: { lhs.wrappedValue = $0 }
    )
}

一种可能的解决方案是创建自定义扩展:

extension Binding {
    func unwrapped<Wrapped>(
        defaultValue: Wrapped
    ) -> Binding<Wrapped> where Value == Wrapped? {
        .init(
            get: { wrappedValue ?? defaultValue },
            set: { wrappedValue = $0 }
        )
    }
}

TextField需要绑定,而不是绑定。看来你不能。您能详细说明一下为什么需要这样的绑定吗?我有一个Contact-NSManaged对象,其属性为
twitter:String?
,允许用户使用textfield将twitter帐户与联系人关联。您可以改为使用空字符串吗<代码>@State var test=“”?如果不是,那么当字符串为
nil
时,您想对
TextField
做些什么?是-问题是核心数据创建了NSManaged字符串作为可选项提交了反馈助手报告,请求可选绑定FB7619680。这非常好,因为它完全可以工作!我觉得必须有更好的方法,因为
绑定有一个更好的方法。我只是不知道如何用它快速速记。这绝对是天才!!!奇妙的解决方案!我不明白,为什么SwiftUI不支持开箱即用…你在哪里写这个函数?@johndoe只是一个全局函数。只是个接线员overload@johndoe你创建了一个新的swift文件,第一行是“导入SwiftUI”,然后在下面粘贴他的代码。
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"))