通过引用传递 @Published var 到视图中的函数
Pass @Published var by reference to function from View
我正在处理附加了 ViewModel 的注册屏幕。
ViewModel 只是一个 class,它扩展了我的注册屏幕 class,我在其中放置了我所有的业务逻辑。
extension RegistrationScreen {
@MainActor class ViewModel : ObservableObject {
//business logic goes here
}
}
ViewModel 有 @Published 变量来表示屏幕中每个文本字段的两种状态:文本和验证文本。
@Published var first: String = ""
@Published var firstValidationMessage: String = ""
在那个 ViewModel 中,我从另一个 class 调用了一个辅助函数,它检查字段的文本是否为空,如果是,它可以将字段验证文本设置为错误,看起来像这个:
class FieldValidation: Identifiable {
func isFieldEmptyAndSetError(fieldText:String, fieldValidationText:Binding<String>) -> Bool {
if(fieldText.isEmpty){
fieldValidationText.wrappedValue = "Required"
return true
}else{
fieldValidationText.wrappedValue = ""
return false
}
}
}
要从我的 viewModel 调用该函数,我执行以下操作:
FieldValidation().isFieldEmptyAndSetError(fieldText:first,fieldValidationText: firstValidationMessage)
这会抛出运行时错误,这对我来说很难解密,因为我通常是 Xcode 和 iOS 的新手。
我的问题是,我怎样才能让这个通过引用传递工作?或者,如果我的做法不可行,请解释发生了什么。
接收一个 @Published
作为参数的函数有点奇怪,如果你想处理 viewModel 中的所有验证,这似乎是 Combine
的一个简单解决方案。我建议您创建一个扩展来验证字符串是否为空,因为 .isEmpty
不 trim 文本。
class
class FieldValidation: Identifiable {
static func isFieldEmptyAndSetError(fieldText:String) -> String {
return fieldText.isEmpty ? "Required" : ""
}
}
视图模型
import Foundation
import Combine
class viewModel: ObservableObject {
@Published var text1 = ""
@Published var text2 = ""
@Published var text3 = ""
@Published var validationText1 = ""
@Published var validationText2 = ""
@Published var validationText3 = ""
init() {
self.$text1.map{newText in FieldValidation.isFieldEmptyAndSetError(fieldText: newText)}.assign(to: &$validationText1)
self.$text2.map{newText in FieldValidation.isFieldEmptyAndSetError(fieldText: newText)}.assign(to: &$validationText2)
}
func validateText(value: String) {
self.validationText3 = FieldValidation.isFieldEmptyAndSetError(fieldText: value)
}
}
视图将如下所示:
import SwiftUI
struct ViewDate: View {
@StateObject var myviewModel = viewModel()
var body: some View {
VStack{
Text("Fill the next fields:")
TextField("", text: $myviewModel.text1)
.border(Color.red)
Text(myviewModel.validationText1)
TextField("", text: $myviewModel.text2)
.border(Color.blue)
Text(myviewModel.validationText2)
TextField("", text: $myviewModel.text3)
.border(Color.green)
.onChange(of: myviewModel.text3) { newValue in
if(newValue.isEmpty){
self.myviewModel.validateText(value: newValue)
}
}
Text(myviewModel.validationText3)
}.padding()
}
}
我正在处理附加了 ViewModel 的注册屏幕。
ViewModel 只是一个 class,它扩展了我的注册屏幕 class,我在其中放置了我所有的业务逻辑。
extension RegistrationScreen {
@MainActor class ViewModel : ObservableObject {
//business logic goes here
}
}
ViewModel 有 @Published 变量来表示屏幕中每个文本字段的两种状态:文本和验证文本。
@Published var first: String = ""
@Published var firstValidationMessage: String = ""
在那个 ViewModel 中,我从另一个 class 调用了一个辅助函数,它检查字段的文本是否为空,如果是,它可以将字段验证文本设置为错误,看起来像这个:
class FieldValidation: Identifiable {
func isFieldEmptyAndSetError(fieldText:String, fieldValidationText:Binding<String>) -> Bool {
if(fieldText.isEmpty){
fieldValidationText.wrappedValue = "Required"
return true
}else{
fieldValidationText.wrappedValue = ""
return false
}
}
}
要从我的 viewModel 调用该函数,我执行以下操作:
FieldValidation().isFieldEmptyAndSetError(fieldText:first,fieldValidationText: firstValidationMessage)
这会抛出运行时错误,这对我来说很难解密,因为我通常是 Xcode 和 iOS 的新手。
我的问题是,我怎样才能让这个通过引用传递工作?或者,如果我的做法不可行,请解释发生了什么。
接收一个 @Published
作为参数的函数有点奇怪,如果你想处理 viewModel 中的所有验证,这似乎是 Combine
的一个简单解决方案。我建议您创建一个扩展来验证字符串是否为空,因为 .isEmpty
不 trim 文本。
class
class FieldValidation: Identifiable {
static func isFieldEmptyAndSetError(fieldText:String) -> String {
return fieldText.isEmpty ? "Required" : ""
}
}
视图模型
import Foundation
import Combine
class viewModel: ObservableObject {
@Published var text1 = ""
@Published var text2 = ""
@Published var text3 = ""
@Published var validationText1 = ""
@Published var validationText2 = ""
@Published var validationText3 = ""
init() {
self.$text1.map{newText in FieldValidation.isFieldEmptyAndSetError(fieldText: newText)}.assign(to: &$validationText1)
self.$text2.map{newText in FieldValidation.isFieldEmptyAndSetError(fieldText: newText)}.assign(to: &$validationText2)
}
func validateText(value: String) {
self.validationText3 = FieldValidation.isFieldEmptyAndSetError(fieldText: value)
}
}
视图将如下所示:
import SwiftUI
struct ViewDate: View {
@StateObject var myviewModel = viewModel()
var body: some View {
VStack{
Text("Fill the next fields:")
TextField("", text: $myviewModel.text1)
.border(Color.red)
Text(myviewModel.validationText1)
TextField("", text: $myviewModel.text2)
.border(Color.blue)
Text(myviewModel.validationText2)
TextField("", text: $myviewModel.text3)
.border(Color.green)
.onChange(of: myviewModel.text3) { newValue in
if(newValue.isEmpty){
self.myviewModel.validateText(value: newValue)
}
}
Text(myviewModel.validationText3)
}.padding()
}
}