UITextField 未更新以更改 ObservableObject (SwiftUI)
UITextField not updating to change in ObservableObject (SwiftUI)
我正在尝试制作一个编辑值 currentDisplayedAddress
的 UITextView。该值也被其他视图更改,我希望 UITextView 在发生这种情况时更新其文本。
视图正确初始化,我可以毫无问题地从 AddressTextField
编辑 currentDisplayedAddress
并触发相关视图更新。但是,当值被其他视图更改时,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
}
}
}
您不应将 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
}
}
}
我正在尝试制作一个编辑值 currentDisplayedAddress
的 UITextView。该值也被其他视图更改,我希望 UITextView 在发生这种情况时更新其文本。
视图正确初始化,我可以毫无问题地从 AddressTextField
编辑 currentDisplayedAddress
并触发相关视图更新。但是,当值被其他视图更改时,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
}
}
}
您不应将 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
}
}
}