首页 > 解决方案 > 为什么 ObservedObject 更新时 ChildView 中的绑定没有更新?

问题描述

这是我的代码,当用户输入 customTextField 时,ObservedObject 视图模型中的用户名会更新,但if text.isEmptyCustomTextField 中的行不运行。如果我尝试通过 @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)
            
            
        }

标签: swiftswiftui

解决方案


原因在于ObservableObject为父类生成的默认发布者。假设您的BaseViewModelis-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

推荐阅读