当 ObservedObject 更新时,为什么我在 ChildView 中的绑定没有更新?

时间:2021-01-21 10:52:01

标签: swift swiftui

这是我的代码,当用户输入 customTextField 时,ObservedObject 视图模型中的用户名会更新,但 CustomTextField 中的行 if text.isEmpty 不会运行。 如果我尝试通过 @State => 使用 testUsername,它会起作用。但是我想使用 ObservedObject,你能帮我吗?谢谢!

    struct CustomTextField: View {
            var placeholder: Text
            @Binding var text: String
            var editingChanged: (Bool)->() = { _ in }
            var commit: ()->() = { }
            
            var body: some View {
                ZStack(alignment: .leading) {
                    if text.isEmpty {
                        placeholder
                            .customPlaceHolderStyle()
                            .padding()
                    }
                    TextField("", text: $text, onEditingChanged: editingChanged, onCommit: commit)
                        .customTextFieldStyle()
                        .padding()
                }.background(Color.colorPrimaryDark)
                
            }
        }
    
    
    struct LoginView: View {
            @ObservedObject var viewModel : LoginViewModel
            
            @State var testUsername : String = ""
            
            var body: some View {
                BaseView(content: VStack(content: {
                    Image("logo_header")
                        .padding()
                    CustomTextField(placeholder: Text(NSLocalizedString("lb_username", comment: "")), text: $viewModel.username, commit:  {
                        UIApplication.shared.endEditing()
                    })
                    
                }).padding() , viewModel: viewModel)
            }
        }
    
    class LoginViewModel : BaseViewModel {
            private var authRepository: AuthRepository? = nil
            @Published var username : String = ""
            @Published var password : String = ""
            
            private init(authRepository : AuthRepository) {
                self.authRepository = authRepository
            }
            
            static let share : LoginViewModel = LoginViewModel(authRepository: AuthRepositoryImpl.share)
            
            
        }

1 个答案:

答案 0 :(得分:0)

原因是在为父类生成的 ObservableObject 的默认发布者中。假设您的 BaseViewModel is-a ObservableObject,您的情况的解决方案是

class LoginViewModel : BaseViewModel {
        private var authRepository: AuthRepository? = nil
        
        var username : String = "" {
           willSet {  // in some cases didSet should be used
              self.objectWillChange.send()
           }
        }
        
        // do the same for 'password' property

作为替代,您可以尝试合并发布商,例如

class LoginViewModel : BaseViewModel {
    // ... other code

    override init() {
        super.init()
        _ = self.objectWillChange.append(super.objectWillChange)
    }
// ... other code