![](/img/trans.png)
[英]iOS15, link between text is disappear every time when I click on another list’s text
[英]Why does Text disappear when i click submit?
当我在 EditText 视图中输入以填写所有必需的信息,然后单击提交时。 我输入的所有内容都消失了。 我希望保留此文本。 我猜我的@State
对象有问题,但无法弄清楚是什么。
注册视图模型
class SignUpViewModel : ObservableObject {
@Published
var error: String? = nil
@Published
var goHome: Bool = false
@Published
var goToLogin: Bool = false
func onGoToLoginClicked() {
self.goToLogin = true
}
func signUp(firstName: String, lastName: String, email: String, birthday: String, phoneNumber: String, password: String, confirmPassword: String) {
if (firstName.count < 3) {
error = "Please enter first name"
return
}
if (lastName.count < 3) {
error = "Please enter last name"
return
}
if (!email.isEmail()) {
error = "Pleaes enter valid email"
return
}
if (birthday.isEmpty) {
error = "Pleae enter valid birthday"
return
}
if (!phoneNumber.isDigits) {
error = "Please enter valid phone number"
return
}
if (password.count < 8) {
error = "Please enter a password that is at least 8 characters long"
}
if (password != confirmPassword) {
error = "Password do not match"
}
Auth.auth().createUser(withEmail: email, password: password, completion: { authResult, error in
if authResult != nil {
self.goHome = true
} else {
self.error = error?.localizedDescription
}
})
}
}
注册视图
struct SignUpScreen: View {
@State
var firstName: String = ""
@State
var lastName: String = ""
@State
var birthday: String = ""
@State
var number: String = ""
@State
var email: String = ""
@State
var password: String = ""
@State
var confirmPassword: String = ""
@EnvironmentObject
var viewModel: SignUpViewModel
var body: some View {
ZStack {
VStack {
VClearBackground()
Spacer()
}
ScrollView {
VStack(alignment: .leading) {
Group {
PreHeaderText(header: "Get Started")
.alignmentGuide(.leading, computeValue: { d in
d[.leading]
})
.padding(EdgeInsets.init(top: 32, leading: 0, bottom: 0, trailing: 0))
HeaderText(header: "Create Account")
EditText(hint: "Huey", text: $firstName, label: "FIRST NAME", textContentType: UITextContentType.name)
EditText(hint: "Freeman", text: $lastName, label: "LAST NAME", textContentType: UITextContentType.name)
EditText(hint: "04-19-1994", text: $birthday, label: "BIRTHDAY")
EditText(hint: "(281) 456-7890)", text: $number, label: "MOBILE NUMBER", textContentType: UITextContentType.telephoneNumber, keyboardType: UIKeyboardType.phonePad)
EditText(hint: "email@exmaple.com", text: $email, label: "EMAIL", textContentType: UITextContentType.emailAddress)
EditText(hint: "********", text: $password, label: "PASSWORD", textContentType: UITextContentType.newPassword)
EditText(hint: "********", text: $confirmPassword, label: "CONFIRM PASSWORD", textContentType: UITextContentType.newPassword)
}
Group {
if self.viewModel.error != nil {
HStack {
Spacer()
Text(viewModel.error ?? "")
.foregroundColor(ColorTheme.error.color)
Spacer()
}
.padding()
}
HStack {
Spacer()
VowerButton(text: "Submit") {
self.viewModel.signUp(firstName: self.firstName, lastName: self.lastName, email: self.email, birthday: self.birthday, phoneNumber: self.number, password: self.password, confirmPassword: self.confirmPassword)
}
Spacer()
}
.padding()
HStack {
Spacer()
NavigationLink(destination: LoginScreen(), isActive: $viewModel.goToLogin) {
CtaText(text: "Have an account?", cta: "Login") {
self.viewModel.onGoToLoginClicked()
}
}
.padding()
Spacer()
}
Spacer()
}
}
}
.padding(EdgeInsets.init(top: 16, leading: 16, bottom: 16, trailing: 16))
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
}
.background(LinearGradient(gradient: Gradient(colors: [.black, ColorTheme.brandPurple.color]), startPoint: .top, endPoint: .bottom))
.edgesIgnoringSafeArea(.all)
}
}
编辑文本视图
struct EditText: View {
var hint: String
@Binding
var text: String
var label: String = ""
var defaultValue = ""
var textContentType: UITextContentType? = .none
var keyboardType: UIKeyboardType = .default
private func initializeDefaultValue() {
DispatchQueue.main.async {
self.text = self.defaultValue
}
}
var body: some View {
initializeDefaultValue()
return VStack(alignment: .leading) {
Text(label).font(.system(size: 12)).bold()
.foregroundColor(ColorTheme.text.color)
HStack {
TextField(hint, text: $text)
.lineLimit(1)
.textContentType(textContentType)
.keyboardType(keyboardType)
.foregroundColor(ColorTheme.text.color)
}
Divider().background(Color(ColorTheme.brandBlue.value))
}
.padding(EdgeInsets.init(top: 12, leading: 0, bottom: 8, trailing: 0))
}
}
问题代码在SignUpScreen
:
@ObservedObject
var viewModel: SignUpViewModel = SignUpViewModel()
每当重新评估视图时, SignUpViewModel
创建一个新的SignUpViewModel
。
您可以在视图之外创建视图模型,并将其直接传递给构造函数,或者使用environmentObject()
将其注入environmentObject()
。
要改用环境对象,请将上述声明更改为:
@EnvironmentObject
var viewModel: SignUpViewModel
然后像这样创建你的视图:
var signUpViewModel = SignUpViewModel()
// ...
SignUpScreen()
.environmentObject(signUpViewModel)
问题出在您的EditText
视图中。
struct EditText: View {
var hint: String
@Binding
var text: String
var label: String = ""
var defaultValue = ""
var textContentType: UITextContentType? = .none
var keyboardType: UIKeyboardType = .default
private func initializeDefaultValue() {
DispatchQueue.main.async {
self.text = self.defaultValue
}
}
var body: some View {
initializeDefaultValue()
return VStack(alignment: .leading) {
Text(label).font(.system(size: 12)).bold()
.foregroundColor(ColorTheme.text.color)
HStack {
TextField(hint, text: $text)
.lineLimit(1)
.textContentType(textContentType)
.keyboardType(keyboardType)
.foregroundColor(ColorTheme.text.color)
}
Divider().background(Color(ColorTheme.brandBlue.value))
}
.padding(EdgeInsets.init(top: 12, leading: 0, bottom: 8, trailing: 0))
}
}
具体来说,它在body
属性中。 这是一个计算属性,每当重新计算视图时,SwiftUI 都会获取它。 在这种情况下,当SignUpScreen
视图的error
属性更改时会发生这种情况,因为所有子视图都被重新计算。
重新计算此EditText
视图时,将调用initializeDefaultValue()
函数(它是body
属性中的第一行)。 这将清除文本字段。
至于解决方案,我不确定为什么您实际上完全需要initializeDefaultValue
函数。 它似乎最适合 ViewModel 或其他一些位置。
另外,我看到的其他一些东西:
func signUp(firstName: String, lastName: String, email: String, birthday: String, phoneNumber: String, password: String, confirmPassword: String) {
if (firstName.count < 3) {
error = "Please enter first name"
return
}
if (lastName.count < 3) {
error = "Please enter last name"
return
}
if (!email.isEmail()) {
error = "Pleaes enter valid email"
return
}
if (birthday.isEmpty) {
error = "Pleae enter valid birthday"
return
}
if (!phoneNumber.isDigits) {
error = "Please enter valid phone number"
return
}
if (password.count < 8) {
error = "Please enter a password that is at least 8 characters long"
}
if (password != confirmPassword) {
error = "Password do not match"
}
Auth.auth().createUser(withEmail: email, password: password, completion: { authResult, error in
if authResult != nil {
self.goHome = true
} else {
self.error = error?.localizedDescription
}
})
}
除了最后两个错误,这个函数在所有错误情况下都会提前返回——我认为这是一个错误。
if self.viewModel.error != nil {
HStack {
Spacer()
Text(viewModel.error ?? "")
.foregroundColor(ColorTheme.error.color)
Spacer()
}
.padding()
}
SignUpScreen
视图的这一部分应该能够简化为:
if let err = self.viewModel.error {
HStack {
Spacer()
Text(err)
.foregroundColor(ColorTheme.error.color)
Spacer()
}
.padding()
}
或者,如果在这种情况下不允许使用 if-let 语句:
if self.viewModel.error != nil {
HStack {
Spacer()
Text(viewModel.error!)
.foregroundColor(ColorTheme.error.color)
Spacer()
}
.padding()
}
如您所知,错误是非nil
。
希望所有这些都有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.