通过引用传递 @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()
        }
    }