Greetings,
I'm currently evaluating SwiftUI, and looking to replicate the common functionality
of disabling a button until text/string are entered in 2 fields.
Common Scenario:
A login screen with UserName & Password enables the Login Button once values
are contained. This is a simple affair on Swift using typical UIKit.
This is accomplished quite simply with property observers and leveraging didSet, and a function to check.
I can post this code, however it's not important here.
With SwiftUI, Is there a suggested approach to Bind two fields to a button?
I've experimented with a few things like onEditingChanged, and onCommit.
A simplified version here:
import SwiftUI
struct ContentView: View {
@State private var username = ""
@State private var password = ""
var body: some View {
NavigationView{
VStack {
TextField("enter user name", text: $username, onEditingChanged: { (changed) in
print("editing \(self.username)")
}) {
print("committed \(self.username)")
}
.padding(10)
SecureField("enter a password", text: $password, onCommit: { () in
print("committed password \(self.password)")
})
.padding(10)
Button(action: {
// show next screen here/nav
}) {
Text("Login")
.padding(10)
.font(.title)
Spacer()
}.padding(10)
.disabled(true) // ideally pass this a condition where both username and password have values
}
}
}
}
I've also created a custom button as such, but no luck just yet
struct RoundedButton : View {
@Binding var usernameEntered: Bool
@Binding var passwordEntered: Bool
var body: some View {
Button(action: {}) {
HStack{
Spacer()
Text("Login")
.padding(10)
.font(.title)
Spacer()
}
}
.disabled(passwordEntered && usernameEntered)
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
Thoughts anyone?
So long as the condition passed to
.disabled()
makes use of @State
variables or similar, it will be automatically re-evaluated when those variables change (or rather, the view's body
will be invoked again, thus running the check). Ultimately all you need to do is use the content of the username
and password
properties to create your condition.Here's an example that disables the button if either the username or password is empty:
struct ContentView: View {
@State private var username = ""
@State private var password = ""
var body: some View {
VStack {
TextField("enter user name", text: $username)
.padding(10)
SecureField("enter a password", text: $password)
.padding(10)
Button(action: {
// show next screen here/nav
}) {
Text("Login")
.padding(10)
.font(.title)
Spacer()
}
.padding(10)
.disabled(username.isEmpty || password.isEmpty)
}
}
}