swift - SwiftUI:如何在 UIViewRepresentable UITextField 上调用 becomeFirstResponder 时修复“通过属性检测到的 AttributeGraph 循环”
问题描述
我正在尝试使用其标记属性和@Binding 将文本字段设置为第一响应者。由于我无法从 SwiftUI TextField 访问底层 UITextField 并.becomeFirstResponder()
直接调用,因此我必须使用UIViewRepresentable
. 下面的代码有效,但会导致以下控制台消息=== AttributeGraph: cycle detected through attribute <#> ===
。
听起来我有内存泄漏和/或保留周期,我已将问题隔离到线路textField.becomeFirstResponder()
但检查了 Xcode 的内存图层次结构我看不出有什么问题?
非常感谢提供的任何帮助。
struct CustomTextField: UIViewRepresentable {
var tag: Int
@Binding var selectedTag: Int
@Binding var text: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: ResponderTextField
init(_ textField: ResponderTextField) {
self.parent = textField
}
func textFieldDidChangeSelection(_ textField: UITextField) {
parent.text = textField.text ?? ""
}
}
func makeUIView(context: Context) -> UITextField {
let textField = UITextField(frame: .zero)
textField.tag = tag
textField.delegate = context.coordinator
return textField
}
func updateUIView(_ textField: UITextField, context: Context) {
if textField.tag == selectedTag, textField.window != nil, textField.isFirstResponder == false {
textField.becomeFirstResponder()
}
}
}
解决方案
凭直觉,我将 becomeFirstResponder() 放入异步调度中。这修复了警告。我猜在创建视图时会发生某种创建循环,并且您调用 becomeFirstResponder(),以便调用视图,这会触发 SwiftUI 找到它尚未正确创建的视图(或其他东西像那样)
无论如何-这对我有用:
func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<UITextViewWrapper>) {
if uiView.text != self.text {
uiView.text = self.text
}
if uiView.window != nil, !uiView.isFirstResponder {
//This triggers attribute cycle if not dispatched
DispatchQueue.main.async {
uiView.becomeFirstResponder()
}
}
}
推荐阅读
- python - 显示变量错误pyautogui
- xml - Spring saml:为什么在 saml 响应中,可以加密密钥信息?
- elixir - 从 escript 访问 IEx.pry
- oracle - ANT - PLSQL 执行错误
- bitbake - 如何让 Openembedded 编译 tar.gz 文件而不是 tar.xz
- javascript - Javascript 承诺在使用 Promise.all 时无法正常工作
- c# - 从服务器推送时 SignalR 重用逻辑
- c# - 使用 LINQ 从日期范围内的列表中选择不同
- batch-file - 如何将“网络用户”输出设置为等于变量
- ios - UITableView 作为 inputView 未显示在 UICollectionView 单元格中