SwiftUI:仅当输入不为空时才启用保存按钮

And*_*rew 5 swift swiftui combine

我有一个带有两个文本字段和一个保存按钮的视图。如何根据文本字段的内容更改按钮的状态(我只想在所有文本字段不为空的情况下启用按钮)?这是我当前的代码:

// The variables associated with text fields
@State var name: String = ""
@State var type: String = ""

// I'd like to associate this variable with
// my button's disabled / enabled state,
// but the function responsible for it doesn't accept bindings
@State var canSave: Bool = false

var body: some View {
    Form {
        TextField("Name", text: $name)
        TextField("Type", text: $type)

        Button(action: {
            // ...
        }, label: {
            Text("Save")
        })
            .disabled(!canSave) // no bindings allowed here; what to use indead?
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个想法,我应该combineLatest从最新的 Combine 框架中使用它。但是无论我尝试谷歌搜索什么,都会引导我找到与 RxSwift 相关的主题,而不是实际的 Combine 实现。

mat*_*att 6

您似乎对 SwiftUI 的工作方式有误解。它不依赖于绑定上的下坡数据流。它完全取决于状态变量。上坡流取决于绑定,但您在需要它们的地方得到了那些(除了您的代码错误:您已将两个文本字段绑定到同一个绑定)。

因此,在像这样的简单情况下,您不需要绑定或组合。你有状态变量,这就是你所需要的:

struct ContentView: View {
    @State var name: String = ""
    @State var type: String = ""
    var body: some View {
        Form {
            TextField("Name", text: $name)
            TextField("Type", text: $type)
            Button(action: {
                // ...
            }, label: {
                Text("Save")
            }).disabled(name.isEmpty || type.isEmpty)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您有许多文本字段需要验证,而不仅仅是一两个,那么当然可以使用发布和订阅将它们组合成一个 Bool。但让我们首先了解基本原则。