How to add a 'Done' button to numpad keyboard in iOS

George McKibbin picture George McKibbin · Nov 25, 2013 · Viewed 71.6k times · Source

So, the numpad keyboard doesn't come with a 'Done' or 'Next' button by default so I'd like to add one. In iOS 6 and below there were some tricks to add a button to the keyboard but they don't seem to be working in iOS 7.

First I subscribe to the keyboard showing notification

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

Then I try to add a button when the keyboard shows up:

- (void)keyboardWillShow:(NSNotification *)note 
{
    // create custom button
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeSystem];
    doneButton.frame = CGRectMake(0, 50, 106, 53);
    doneButton.adjustsImageWhenHighlighted = NO;
    [doneButton setTitle:@"Done" forState:UIControlStateNormal];
    [doneButton addTarget:self action:@selector(dismissKeyboard) forControlEvents:UIControlEventTouchUpInside];

    // locate keyboard view
    UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    UIView* keyboard;
    for(int i=0; i<[tempWindow.subviews count]; i++) 
    {
        keyboard = [tempWindow.subviews objectAtIndex:i];
        // keyboard view found; add the custom button to it
        if([[keyboard description] hasPrefix:@"UIKeyboard"] == YES)
        [keyboard addSubview:doneButton];
    }
}

But the for loop doesn't run because it doesn't find any subviews. Any suggestions? I couldn't find any solutions for iOS7 so is there a different way I'm supposed to be doing this?

Edit: Thanks for all the suggestions for toolbars guys but I'd rather not go down that route as I'm quite space poor (and it is kind of ugly).

Answer

Bhavin picture Bhavin · Nov 25, 2013

The much safer approach is to use a UIToolBar with Done Button as inputAccessoryView.


Sample Code :

UIToolbar *keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
                                                               style:UIBarButtonItemStyleBordered target:self
                                                              action:@selector(doneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
txtField.inputAccessoryView = keyboardDoneButtonView;

Your -doneClicked method should look like this :

- (IBAction)doneClicked:(id)sender
{
    NSLog(@"Done Clicked.");
    [self.view endEditing:YES];
}

Sample Code Swift:

let keyboardDoneButtonView = UIToolbar.init()
keyboardDoneButtonView.sizeToFit()
let doneButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Done, 
                                                   target: self, 
                                                   action: Selector("doneClicked:")))    

keyboardDoneButtonView.items = [doneButton]
textFieldInput.inputAccessoryView = keyboardDoneButtonView

Your -doneClicked method should look like this :

func doneClicked(sender: AnyObject) {
  self.view.endEditing(true)
}