So I feel stupid asking about this, but I simply cannot figure out what is going wrong. Basically, when I click a textField that has a UIPickerView as its inputView
it will show up very quickly and then disappear. However, the toolBar (its accessoryView
still remains on screen). I haven't seen anyone else online who has experienced this, so that's why I had to ask it on SO.
At first I thought it had something do with when I was setting the pickerView's .isHidden
property. But I omitted those calls to no effect.
Thus, I will be including all of the code related to my pickerViews since I really don't know where the issue is. I'm sure it's something minor I'm missing, but any help would be appreciated.
class myAssessmentsViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
@IBOutlet weak var contentSelectionTextField: UITextField!
@IBOutlet weak var contentOrderingTextField: UITextField!
var contentSelectionPickerView: UIPickerView = UIPickerView()
var contentOrderingPickerView: UIPickerView = UIPickerView()
var contentSelectionOptions: [String] = ["All", "Physics HL", "Chemistry HL", "Spanish Ab SL"]
var contentOrderingOptions: [String] = ["Date", "Subject", "Grade", "Title"]
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
contentSelectionPickerView.tag = 1 //for the delegate methods
contentSelectionPickerView.isHidden = true //commenting this out did nothing
contentSelectionPickerView.delegate = self
contentSelectionPickerView.dataSource = self
contentSelectionTextField.inputView = contentSelectionPickerView //set pickerView as responder
contentSelectionTextField.delegate = self
contentOrderingPickerView.tag = 2 //for the delegate methods
contentOrderingPickerView.isHidden = true //commenting this out also did nothing
contentOrderingPickerView.delegate = self
contentOrderingPickerView.dataSource = self
initializePickerViewToolBar(clearButtonFunc: "clearPressedContentSelectionPickerView", doneButtonFunc: "donePressedContentSelectionPickerView", textField: contentSelectionTextField)
initializePickerViewToolBar(clearButtonFunc: "clearPressedContentOrderingPickerView", doneButtonFunc: "donePressedContentOrderingPickerView", textField: contentOrderingTextField)
contentOrderingTextField.inputView = contentOrderingPickerView //set pickerView as responder
contentOrderingTextField.delegate = self
// Do any additional setup after loading the view.
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1 //same for both pickers
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 1 { //contentSelectionPickerView
return contentSelectionOptions.count
} else if pickerView.tag == 2 { //contentOrderingPickerView
return contentOrderingOptions.count
} else {
return 1
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
self.view.endEditing(true)
if pickerView.tag == 1 { //contentSelectionPickerView
return contentSelectionOptions[row]
} else if pickerView.tag == 2 { //contentOrderingPickerView
return contentOrderingOptions[row]
} else {
return "1"
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView.tag == 1 {
contentSelectionTextField.text = contentSelectionOptions[row]
} else if pickerView.tag == 2 {
contentOrderingTextField.text = contentOrderingOptions[row]
}
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == contentSelectionTextField {
contentSelectionPickerView.isHidden = false //also was not source of problem
} else if textField == contentOrderingTextField {
contentOrderingPickerView.isHidden = false //same here
}
}
func donePressedContentSelectionPickerView(){
contentSelectionTextField.resignFirstResponder()
}
func donePressedContentOrderingPickerView(){
contentOrderingTextField.resignFirstResponder()
}
func clearPressedContentSelectionPickerView(){
contentSelectionTextField.resignFirstResponder()
contentSelectionTextField.text = ""
}
func clearPressedContentOrderingPickerView(){
contentOrderingTextField.resignFirstResponder()
contentOrderingTextField.text = ""
}
func initializePickerViewToolBar(clearButtonFunc: String, doneButtonFunc: String, textField: UITextField){
let toolBar = UIToolbar(frame: CGRect(x: 0, y: textField.frame.size.height/6, width: textField.frame.size.width, height: 40.0))
toolBar.layer.position = CGPoint(x: textField.frame.size.width/2, y: textField.frame.size.height-20.0)
toolBar.barStyle = .default
toolBar.tintColor = UIColor.black
let clearButton = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: Selector(clearButtonFunc))
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: Selector(doneButtonFunc))
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
toolBar.setItems([clearButton,flexSpace,doneButton], animated: true)
toolBar.isUserInteractionEnabled = true
textField.inputAccessoryView = toolBar
}
}
Here is also a photo of what I am talking about visually. As you can see at the bottom of the screen the accessoryView is still visible but the content isn't. I would think that the accessoryView would be a subview of the UIPickerView and that they would disappear together but that is apparently not the case.
Again, apologies for all of the code (and the large image), I know it is a lot to read through, but any insight would be greatly appreciated!
So it turns out that one of the answers from SO that I was following told me to include self.view.endEditing(true)
in my pickerViewTitleForRow delegate method. This meant whenever the titles were being set, the first responder was being dismissed, causing this issue. Removing it caused the problem to disappear. Thanks to @MikeTaverne for pointing it out.