1

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

视图正确初始化,我可以毫无问题地进行编辑并触发相关的视图更新currentDisplayedAddressAddressTextField但是,当值被其他视图更改时,textField 的文本不会更改,即使textField.text在内部打印正确的更新值updateUIView并且其他视图也会相应更新。

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

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
        }
    }
}
4

1 回答 1

0

您不应该创建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
        }
    }
}
于 2020-08-04T13:20:50.150 回答