首页 > 解决方案 > 有没有办法在 SwiftUI 中为 TextField 设置 inputView?

问题描述

我想将选择器设置为 TextField 的 inputView,我可以只使用 SwiftUI 还是必须在框架集成的帮助下使用 UIKit 组件?

UIKit 中的代码示例:

textField.inputView = UIPickerView()

我也想做同样的事情,但是使用 SwiftUI 的 TextField

标签: swiftswiftui

解决方案


我发现使用上述解决方案的唯一问题是,每当键盘进入编辑阶段时,就会出现选择器,并且键盘也会随之出现。

所以没有办法隐藏键盘并呈现选择器。因此,我编写了一个自定义结构来处理这种行为,类似于我们使用 UITextField inputView 所做的。你可以使用它。这适用于我的用例。

您还可以自定义选择器,以及像我一样在 makeUIView 方法中的文本字段,已经完成了选择器的背景颜色。

 struct TextFieldWithPickerAsInputView : UIViewRepresentable {

      var data : [String]
      var placeholder : String

      @Binding var selectionIndex : Int
      @Binding var text : String?

      private let textField = UITextField()
      private let picker = UIPickerView()

      func makeCoordinator() -> TextFieldWithPickerAsInputView.Coordinator {
           Coordinator(textfield: self)
      }

      func makeUIView(context: UIViewRepresentableContext<TextFieldWithPickerAsInputView>) -> UITextField {
           picker.delegate = context.coordinator
           picker.dataSource = context.coordinator
           picker.backgroundColor = .yellow
           picker.tintColor = .black
           textField.placeholder = placeholder
           textField.inputView = picker
           textField.delegate = context.coordinator
           return textField
      }

      func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<TextFieldWithPickerAsInputView>) {
           uiView.text = text
      }

      class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate , UITextFieldDelegate {

           private let parent : TextFieldWithPickerAsInputView

           init(textfield : TextFieldWithPickerAsInputView) {
                self.parent = textfield
           }

           func numberOfComponents(in pickerView: UIPickerView) -> Int {
                return 1
           }
           func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
                return self.parent.data.count
           }
           func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
                return self.parent.data[row]
           }
           func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
                self.parent.$selectionIndex.wrappedValue = row
                self.parent.text = self.parent.data[self.parent.selectionIndex]
                self.parent.textField.endEditing(true)

           }
           func textFieldDidEndEditing(_ textField: UITextField) {
                self.parent.textField.resignFirstResponder()
           }
     }
 }

您可以将其用作:-

 struct ContentView : View {

      @State var gender : String? = nil
      @State var arrGenders = ["Male","Female","Unknown"]
      @State var selectionIndex = 0

      var body : some View {
          VStack {
                   TextFieldWithPickerAsInputView(data: self.arrGenders, placeholder: "select your gender", selectionIndex: self.$selectionIndex, text: self.$gender)
         }
     }
 }

推荐阅读