UPDATE:
I also tried implementing UITextViewDelegate delegate and then doing in my controller:
- (BOOL)textViewShouldEndEditing:(UITextView *)textVie
The following is my approach, in Swift 3
. When the doneBtn
clicked, let it send .editingDidEndOnExit
event. I use this event to handle focus problem between multiple textFields.
// My customized UITextField
class MyTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
// Add toolBar when keyboardType in this set.
let set : [UIKeyboardType] = [.numberPad, .phonePad]
if (set.contains(self.keyboardType) ) {
self.addDoneToolbar()
}
}
// Add a toolbar with a `Done` button
func addDoneToolbar() {
let toolbar = UIToolbar()
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(onToolBarDone))
toolbar.items = [space, doneBtn]
toolbar.sizeToFit()
self.inputAccessoryView = toolbar
}
@objc func onToolBarDone() {
// I use `editingDidEndOnExit` to simulate the `Done` behavior
// on the original keyboard.
self.sendActions(for: .editingDidEndOnExit)
}
}
Add UIToolBar as custom view that will have Done button as UIBarButtonItem in it.
This is safer and cleaner way to add Done button to any Type of Keyboard. Create UIToolBar add Done Button to it and set inputAccessoryView of any UITextField or UITextView.
UIToolbar *ViewForDoneButtonOnKeyboard = [[UIToolbar alloc] init];
[ViewForDoneButtonOnKeyboard sizeToFit];
UIBarButtonItem *btnDoneOnKeyboard = [[UIBarButtonItem alloc] initWithTitle:@"Done"
style:UIBarButtonItemStyleBordered target:self
action:@selector(doneBtnFromKeyboardClicked:)];
[ViewForDoneButtonOnKeyboard setItems:[NSArray arrayWithObjects:btnDoneOnKeyboard, nil]];
myTextField.inputAccessoryView = ViewForDoneButtonOnKeyboard;
IBAction For Done Button
- (IBAction)doneBtnFromKeyboardClicked:(id)sender
{
NSLog(@"Done Button Clicked.");
//Hide Keyboard by endEditing or Anything you want.
[self.view endEditing:YES];
}
SWIFT 3
var ViewForDoneButtonOnKeyboard = UIToolbar()
ViewForDoneButtonOnKeyboard.sizeToFit()
var btnDoneOnKeyboard = UIBarButtonItem(title: "Done", style: .bordered, target: self, action: #selector(self.doneBtnFromKeyboardClicked))
ViewForDoneButtonOnKeyboard.items = [btnDoneOnKeyboard]
myTextField.inputAccessoryView = ViewForDoneButtonOnKeyboard
Function
@IBAction func doneBtnFromKeyboardClicked (sender: Any) {
print("Done Button Clicked.")
//Hide Keyboard by endEditing or Anything you want.
self.view.endEditing(true)
}
Set the 'Return Key'
option under the text field
option in the inspector for your text field.
Then right click on the text field and while holding CTRL
select 'Did End On Exit'
and drag this into your view controllers
file. This will create an IBAction
method. Give the method a name and then enter the following values:
[textField becomeFirstResponder];
[textField resignFirstResponder];
Your method should look like this:
- (IBAction)methodName:(id)sender;
{
[sender becomeFirstResponder];
[sender resignFirstResponder];
}
In Interface Builder on the properties of the textView you can set the return button type to Done.
Then you need to check for when the Return button is pressed using
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
Check if the text == "/n" then dismiss the keyboard by resigning first responder on your textView.
Go into your storyboard, select your text field and under the Attributes Inspector there is an option that says "return key"...select "Done".
Then go into your ViewController and add:
- (IBAction)dismissKeyboard:(id)sender;
{
[textField becomeFirstResponder];
[textField resignFirstResponder];
}
Then go back to your text field, click outlets and link "Did end on exit" to dismissKeyboard action.
thats quite simple :)
[textField setReturnKeyType:UIReturnKeyDone];
for dismissing the keyboard implement the <UITextFieldDelegate>
protocol in your class, set
textfield.delegate = self;
and use
- (void)textFieldDidEndEditing:(UITextField *)textField {
[textField resignFirstResponder];
}
or
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}