How can I use Combine to track UITextField changes in a UIViewRepresentable class?

前端 未结 3 2035
说谎
说谎 2020-12-15 14:37

I have created a custom text field and I\'d like to take advantage of Combine. In order to be notified whenever text changes in my text field, I currently use a custom modif

3条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-15 14:52

    I also needed to use a UITextField in SwiftUI, so I tried the following code:

    struct MyTextField: UIViewRepresentable {
      private var placeholder: String
      @Binding private var text: String
      private var textField = UITextField()
    
      init(_ placeholder: String, text: Binding) {
        self.placeholder = placeholder
        self._text = text
      }
    
      func makeCoordinator() -> Coordinator {
        Coordinator(textField: self.textField, text: self._text)
      }
    
      func makeUIView(context: Context) -> UITextField {
        textField.placeholder = self.placeholder
        textField.font = UIFont.systemFont(ofSize: 20)
        return textField
      }
    
      func updateUIView(_ uiView: UITextField, context: Context) {
      }
    
      class Coordinator: NSObject {
        private var dispose = Set()
        @Binding var text: String
    
        init(textField: UITextField, text: Binding) {
          self._text = text
          super.init()
    
          NotificationCenter.default
            .publisher(for: UITextField.textDidChangeNotification, object: textField)
            .compactMap { $0.object as? UITextField }
            .compactMap { $0.text }
            .receive(on: RunLoop.main)
            .assign(to: \.text, on: self)
            .store(in: &dispose)
        }
      }
    }
    
    struct ContentView: View {
      @State var text: String = ""
    
      var body: some View {
        VStack {
          MyTextField("placeholder", text: self.$text).padding()
          Text(self.text).foregroundColor(.red).padding()
        }
      }
    }
    

提交回复
热议问题