UITextField 未更新以更改 ObservableObject (SwiftUI)

UITextField not updating to change in ObservableObject (SwiftUI)

我正在尝试制作一个编辑值 currentDisplayedAddress 的 UITextView。该值也被其他视图更改,我希望 UITextView 在发生这种情况时更新其文本。

视图正确初始化,我可以毫无问题地从 AddressTextField 编辑 currentDisplayedAddress 并触发相关视图更新。但是,当值被其他视图更改时,textField 的文本不会更改,即使 textField.textupdateUIView 中打印正确的更新值并且其他视图相应地更新。

我不知道是什么原因造成的。非常感谢任何帮助。

struct AddressTextField: UIViewRepresentable {
    private let textField = UITextField(frame: .zero)
    var commit: () -> Void
    @EnvironmentObject var userData: UserDataModel

    func makeUIView(context: UIViewRepresentableContext<AddressTextField>) -> UITextField {
        textField.text = self.userData.currentDisplayedAddress
        textField.delegate = context.coordinator
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<AddressTextField>) {
        if self.textField.text != self.userData.currentDisplayedAddress {
        DispatchQueue.main.async {
            self.textField.text = self.userData.currentDisplayedAddress
            }
        }
    }

   (...)

    func makeCoordinator() -> Coordinator { Coordinator(self) }

    class Coordinator: NSObject, UITextFieldDelegate {
        var addressTextField: AddressTextField

        func textFieldShouldReturn(_ textField: UITextField) -> Bool {   //delegate method
            textField.resignFirstResponder()
            addressTextField.userData.currentDisplayedAddress = textField.text ?? String()
            addressTextField.commit()
            return true
        }
    }
}

您不应将 UITextField 创建为 属性,因为 AddressTextField 结构可以在父更新期间重新创建。 makeUIView 正是创建 UI-instances 的地方,代表正在代表您处理它的引用。

所以这里是固定变体。使用 Xcode 11.4 / iOS 13.4

测试
struct AddressTextField: UIViewRepresentable {
    var commit: () -> Void = {}
    @EnvironmentObject var userData: UserDataModel

    func makeUIView(context: UIViewRepresentableContext<AddressTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.text = self.userData.currentDisplayedAddress
        textField.delegate = context.coordinator
        return textField
    }

    func updateUIView(_ textField: UITextField, context: UIViewRepresentableContext<AddressTextField>) {
        if textField.text != self.userData.currentDisplayedAddress {
            textField.text = self.userData.currentDisplayedAddress
        }
    }

    func makeCoordinator() -> Coordinator { Coordinator(self) }

    class Coordinator: NSObject, UITextFieldDelegate {
        var addressTextField: AddressTextField
        init(_ addressTextField: AddressTextField) {
            self.addressTextField = addressTextField
        }
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {   //delegate method
            textField.resignFirstResponder()
            addressTextField.userData.currentDisplayedAddress = textField.text ?? String()
            addressTextField.commit()
            return true
        }
    }
}