【问题标题】:Cycle detected through use of UIKit Textfield Representable in SwiftUI通过在 SwiftUI 中使用 UIKit Textfield Representable 检测到循环
【发布时间】:2022-01-11 06:19:47
【问题描述】:

我正在使用布尔值 (searchVM.showSearchView: Bool) 同时将 SearchView 的不透明度设置为 1.0 并显示/隐藏 UIRepresentableKeyboard。

当您点击搜索栏并(同时)出现白色搜索视图、文本字段聚焦和键盘显示时,这为我提供了与 Google 地图相同的功能。

但是,每次将 showSearchView 设置为 true 时,都会打印两次以下消息。

=== AttributeGraph:通过属性 320536 检测到循环 ===

=== AttributeGraph:通过属性 318224 检测到循环 ===

为什么我会收到此消息?是不是我的 searchVM 的传递?

搜索视图模型

class SearchViewModel: ObservableObject {

    var text: String = ""    

    @Published var showSearchView: Bool = false 
 
}

文本字段和取消按钮

struct SearchBar: View {
    @ObservedObject var searchVM: SearchViewModel
    @State var text: String = ""
   
    var body: some View {
        HStack {
            FirstResponderTextfield(searchVM: searchVM, text: $text, placeholder: "Search")
            Text("Cancel")
                .onTapGesture {
                    searchVM.showSearchView.toggle()
                }
        }
    }
}

FirstResponderTextField

struct FirstResponderTextfield: UIViewRepresentable {
    
    @ObservedObject var searchVM : SearchViewModel

    @Binding var text: String
    let placeholder: String

    // COORDINATOR
    class TextFieldCoordinator: NSObject, UITextFieldDelegate {

        var control: FirstResponderTextfield
        
        @Binding var text: String // unused but required

        func textFieldDidChangeSelection(_ textField: UITextField) {
           control.searchVM.text = textField.text ?? ""
          
        }

        func textFieldDidEndEditing(_ textField: UITextField) {
            
        }

        init(control: FirstResponderTextfield, text: Binding<String>) {
            self.control = control
            self._text = text
        }
    }

    func makeCoordinator() -> TextFieldCoordinator {
        return TextFieldCoordinator(control: self, text: $text)
    }

    func makeUIView(context: Context) -> some UIView {
        let textField = UITextField()
        textField.delegate = context.coordinator
        textField.placeholder = placeholder
        return textField
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {
        if searchVM.showSearchView {
            uiView.becomeFirstResponder() // show keyboard
        } else {
            uiView.resignFirstResponder() // dismiss keyboard
        }
    }
}

【问题讨论】:

标签: swift swiftui uikit uiviewrepresentable


【解决方案1】:

我通过添加 DispatchQueue.asyncAfter(.now() + 0.05) 解决了这个问题。可能是一种米老鼠的做事方式,但它确实有效!

 func updateUIView(_ uiView: UIViewType, context: Context) {
        // here we check to see if our textfield has become first responder
        if searchVM.showSearchView {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                uiView.becomeFirstResponder() // show keyboard
            }
           
        } else {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                uiView.resignFirstResponder() // dismiss keyboard
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-18
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多