连接组件之间的 SwiftUI 交互
Wire SwiftUI Interaction among 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)
}
因此,一个人输入他们的电子邮件地址,并在他们键入时,emailAddressChangedValue
发出键入的文本。电子邮件地址通过 validateEmail(emailAddress: emailAddressChangedValue)
验证,一旦出现有效的电子邮件地址,该按钮就会启用。但是,我不知道如何更改 $buttonState
将颜色样式从禁用更改为启用。我尝试将它放在 validateEmail
函数中,但是当我这样做时,我收到错误消息 Modifying state during view update, this will cause undefined behavior.
那么,如何在 VStack 中更新 buttonState
?
假设 TextEdit
类似于 TextField
或 TextEditor
,您可以尝试将 .onReceive{}
添加到“...在堆栈。” (注意,你需要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)
}
我正在尝试连接两个组件:
@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)
}
因此,一个人输入他们的电子邮件地址,并在他们键入时,emailAddressChangedValue
发出键入的文本。电子邮件地址通过 validateEmail(emailAddress: emailAddressChangedValue)
验证,一旦出现有效的电子邮件地址,该按钮就会启用。但是,我不知道如何更改 $buttonState
将颜色样式从禁用更改为启用。我尝试将它放在 validateEmail
函数中,但是当我这样做时,我收到错误消息 Modifying state during view update, this will cause undefined behavior.
那么,如何在 VStack 中更新 buttonState
?
假设 TextEdit
类似于 TextField
或 TextEditor
,您可以尝试将 .onReceive{}
添加到“...在堆栈。” (注意,你需要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)
}