UITextField 未更新以更改 ObservableObject (SwiftUI)

Posted

技术标签:

【中文标题】UITextField 未更新以更改 ObservableObject (SwiftUI)【英文标题】:UITextField not updating to change in ObservableObject (SwiftUI) 【发布时间】:2020-08-04 11:35:04 【问题描述】:

我正在尝试制作一个编辑值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
        
    

【问题讨论】:

【参考方案1】:

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

所以这里是固定的变体。使用 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
        
    

【讨论】:

以上是关于UITextField 未更新以更改 ObservableObject (SwiftUI)的主要内容,如果未能解决你的问题,请参考以下文章

更新字段时,UITextField“值已更改”未触发

UITextfield 值已成功更新,但未显示在表格中

为啥在完成块中更改 .text 字段时 UITextField 和 UILabel 不更新?

UITextField 更改大小以修复文本内容

如何根据 WPF DataGrid 中的更改更新 ObservableCollection 项属性?

编辑时如何更改 UITextField