首页 > 解决方案 > 将关闭键盘添加到 ZStack 时,SwiftUI 选择器停止工作

问题描述

我正在开发一个 SwiftUI 应用程序,该应用程序将 UIViewRepresentable 用于 UIPickerView,它允许 TextField 像 SegmentedPickerView 一样工作。为了退出选择器,我使用了附加到视图的dismissKeyboard 调用。当我将它添加到视图时,作为视图一部分的 SwfitUI 选择器停止响应。我猜这是因为整个视图正在消除选择器。有没有办法解决这个问题?

关闭选择器代码

#if canImport(UIKit)
extension View {
    func dismissKeyboard() {
        let resign = #selector(UIResponder.resignFirstResponder)
        UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
    }
}
#endif

UIViewRepresentable

struct TextFieldWithPickerAsInputView : UIViewRepresentable {
    
    var data : [String]
    var fieldTitle : String
    var function: (() -> Void)? = nil
    @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 = UIColor(Color.pacificBlueAccent)
        picker.tintColor = .black
        textField.placeholder = fieldTitle
        textField.inputView = picker
        textField.font = UIFont(name: Fonts.gse, size: 16.0)
        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) This dismisses the picker when the picker stops moving. Very annoying.
            
        }
        func textFieldDidEndEditing(_ textField: UITextField) {
            if self.parent.function != nil {
                self.parent.function!()
                print("Called")
            }
            self.parent.textField.resignFirstResponder()
        }
    }
}

查看代码

return ZStack {
            Color.pacificBlue
                .edgesIgnoringSafeArea(.all)
            ScrollView(.vertical, showsIndicators: false) {
                VStack {
                    Picker("", selection: self.$listingType) {
                        ForEach(self.listingTypes, id: \.self) {
                            Text($0.uppercased())
                                .font(.custom((Fonts.gse), size: 16))
                                .fontWeight(.medium)
                        }
                    } // Picker
                    .pickerStyle(SegmentedPickerStyle())
                    .frame(width: screen/1.5)
                    .padding(.top, 5)
                    .padding(.bottom, 5)
                    TextFieldWithPickerAsInputView(...)
                } // VStack
            } // ScrollView
        } // ZStack
        .onTapGesture {
            self.dismissKeyboard()
        }

}

标签: swiftui

解决方案


推荐阅读