PaulG
PaulG

Reputation: 7102

iOS 7: How to hide the DONE button on the keyboard

I'm trying to give my users a way to dismiss the keyboard, whether by clicking outside the keyboard or by having a DONE button on the keyboard itself.

I have created a Done button and it works fine on iOS 6:

UIToolbar *keyboardToolbar;

keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - 44, 320, 44)];

UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"dismiss_keyboard", nil) style:UIBarButtonItemStyleDone target:self action:@selector(dismissKeyboard)];

NSArray *items = [NSArray arrayWithObjects:flexItem,doneItem, nil];
[keyboardToolbar setItems:items animated:YES];

for (UIView *subview in [searchBar subviews]) 
{

    if( [subview isKindOfClass:[UITextField class]] )
    {
        ((UITextField*)subview).delegate=self;
        ((UITextField*)subview).inputAccessoryView = keyboardToolbar;
        break;
    }

}

But on iOS 7 this button is no where to be found.

I also tried using the method where the user can click anywhere but the keyboard and make it disappear:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    [super touchesBegan:touches withEvent:event];

    //Code to dismiss keyboard.
}

But my view contains a UISearchBar and a UITableView but the touchesBegan event doesn't fire when I touch those, only when I touch the parent UIView, which is not visible because it's covered by my UISearchBar and my UITableView. I have to touch the tiny space in between the two to fire the event.

How can I make my touchesBegan method apply to any object on the screen? And why is my DONE button not showing up in iOS 7?

Upvotes: 1

Views: 2222

Answers (2)

Balram Tiwari
Balram Tiwari

Reputation: 5667

Use the below approach & get that Done button on your keyboard in iOS7.

Sample code is here.

Screenshot of Done button after using this approach is here.

Upvotes: 0

Aaron Brager
Aaron Brager

Reputation: 66242

Why is my DONE button not showing up in iOS 7?

Your DONE button isn't showing up because the internal structure of UISearchBar, which you aren't supposed to modify, has changed. (This is the reason you're not supposed to modify it.)

If you want to continue this non-recommended behavior and get it working, instead of checking if it's a UITextField, you can try checking if it conforms to UITextInputTraits, and iterate through subviews of subviews:

for(UIView *subView in [searchBar subviews]) {
    if([subView conformsToProtocol:@protocol(UITextInputTraits)]) {
         // iOS 6
         [(UITextField *)subView setReturnKeyType: UIReturnKeyDone];
    } else {
         // iOS 7
        for(UIView *subSubView in [subView subviews]) {
            if([subSubView conformsToProtocol:@protocol(UITextInputTraits)]) {
                [(UITextField *)subSubView setReturnKeyType: UIReturnKeyDone];
        }
    }      
}

(This code is from this SO answer.)

However, this approach is not recommended, because it may break again in iOS 7.1. It also could be more resilient as a recursive method.

How can I make my touchesBegan method apply to any object on the screen?

Touch events are handled by the top view, so the UIView will only get them if the other views don't want them. The easiest approach here is to make an invisible UIButton that covers your whole screen, and if it's tapped, dismiss the keyboard and remove the button.

Upvotes: 1

Related Questions