我想将选择器设置为 TextField 的 inputView,我可以仅使用 SwiftUI 来完成,还是必须在框架集成的帮助下使用 UIKit 组件?
UIKit 中的代码示例:
textField.inputView = UIPickerView()
Run Code Online (Sandbox Code Playgroud)
我想做同样的事情,但使用 SwiftUI 的 TextField
从 Xcode 11.4 开始,SwiftUITextField不具有inputView与UITextField.
UITextField您可以通过将 UIKit 桥接到 SwiftUI 以及将 SwiftUI 桥接到UIKit 来解决此问题Picker。您需要设置文本字段的inputViewController属性而不是其inputView属性。
UITextFieldSwiftUI用于UIViewRepresentable将 包装UITextField在 SwiftUI 中View。由于您创建了UITextField,您可以将其inputViewController属性设置为UIViewController您创建的 a 。
PickerUIKit用于UIHostingController将 SwiftUI 包装Picker在UIViewController. 将文本字段设置inputViewController为您的UIHostingController实例。
我使用上述解决方案发现的唯一问题是,每当键盘进入编辑阶段时,就会出现选择器,并且键盘也会随之出现。
所以没有办法隐藏键盘并显示选择器。因此,我编写了一个自定义结构来处理这种行为,类似于我们使用 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()
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将其用作:-
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6240 次 |
| 最近记录: |