I am trying to wire up two components:
@State private var buttonState = ButtonState.DISABLED
@State private var emailAddressChangedValue = ""
VStack {
TextEdit(editText: $viewModel.email, changedValue: $emailAddressChangedValue, placeholder: NSLocalizedString("onboarding.forgotpassword.email.label", comment: ""), keyboardType: UIKeyboardType.emailAddress)
.padding(.top, 4)
Button(action: {
viewModel.sendPasswordResetRequest()
}, label: {
Text(NSLocalizedString("onboarding.forgotpassword.sendemail.label", comment:""))
.padding()
.font(.headline)
.foregroundColor(Color.white)
})
.buttonStyle(FooButtonStyle(buttonState: $buttonState))
.disabled(!validateEmail(emailAddress: emailAddressChangedValue))
.padding(.top, 8)
.padding(.horizontal, 8)
}
So, a person enters their email address and as they type, the emailAddressChangedValue
emits the typed text. The email address is validated through validateEmail(emailAddress: emailAddressChangedValue)
and once a valid email address occurs, the button becomes enabled. However, I cannot figure out how to change the $buttonState
which changes the color style from disabled to enabled. I tried putting it within the validateEmail
function but when I do that, I receive an error Modifying state during view update, this will cause undefined behavior.
So, how do I update buttonState
within the VStack?
CodePudding user response:
Assuming TextEdit
is like TextField
or TextEditor
, you could try adding .onReceive{}
, like the following example code, to "...update buttonState within the VStack." (note, you need to import Combine
):
VStack {
TextEdit(editText: $viewModel.email, changedValue: $emailAddressChangedValue, placeholder: NSLocalizedString("onboarding.forgotpassword.email.label", comment: ""), keyboardType: UIKeyboardType.emailAddress)
.padding(.top, 4)
Button(action: {
viewModel.sendPasswordResetRequest()
}, label: {
Text(NSLocalizedString("onboarding.forgotpassword.sendemail.label", comment:""))
.padding()
.font(.headline)
.foregroundColor(Color.red)
})
// -- here --
.onReceive(Just(emailAddressChangedValue)) { val in
buttonState = !validateEmail(emailAddress: val)
}
.buttonStyle(FooButtonStyle(buttonState: $buttonState))
.disabled(buttonState) // <-- could also be here
.padding(.top, 8)
.padding(.horizontal, 8)
}