I wrote a UITextfield
extension to build my own toolbar for custom inputs:
func addToolbar(selector: Selector? = nil) {
let action = selector == nil ? #selector(resignFirstResponder) : selector
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: action)
let toolbar = UIToolbar()
toolbar.items = [flexibleSpace, doneButton]
toolbar.sizeToFit()
toolbar.layoutIfNeeded()
inputAccessoryView = toolbar
returnKeyType = .done
}
I use it like this:
let myPickerView = UIPickerView()
myPickerView.dataSource = myPickerViewBehavior
myPickerView.delegate = myPickerViewBehavior
if let selected = value {
let selectedIndex = PickableItemType.index(of: selected.rawValue)
myPickerView.selectRow(selectedIndex, inComponent: 0, animated: true)
}
myTextField.delegate = self
myTextField.inputView = myPickerView
myTextField.addToolbar(selector: #selector(nextTextField.becomeFirstResponder))
As you can imagine I want the next UITextField
to becomeFirstResponder
after the user pressed done in the toolbar.
But nothing happening.
For testing I've tried using a simple @objs func
with print
statement and/or nextTextField.becomeFirstResponder
inside, same result.
I've also tried to use UITapGestureRecognizer
with #selector(nextTextField.becomeFirstResponder)
, also same result.
So I guess it has something to do with the #selector mechanic why the code doesn't work.
P.S.: if selector == nil
inside addToolbar
, #selector(resignFirstResponder)
works fine.
I believe the problem is caused by the wrong target:
while setting up doneButton
.
If you also supply the target in addToolbar:
method like:
func addToolbar(target: Any? = nil, selector: Selector? = nil) {
let object = target ?? self
let action = selector ?? #selector(resignFirstResponder)
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: object, action: action)
let toolbar = UIToolbar()
toolbar.items = [flexibleSpace, doneButton]
toolbar.sizeToFit()
toolbar.layoutIfNeeded()
inputAccessoryView = toolbar
returnKeyType = .done
}
This should work:
firstTextField.addToolbar(target: secondTextField, selector: #selector(becomeFirstResponder))
Here's a small test result: