Search code examples
iosuiviewcontrollernavigationkeyboardmmdrawercontroller

Hide keyboard in iOS for any view?


There are similar questions but they are all about cases when they know which view is editing.

In my case I have a local notification and I want to hide keyboard when app becomes active with it.

In the same time I have a complex navigation which involves MMDrawerController and modal views. So I can't just take topmost view controller and iterate its subviews.

So could you explain how to hide keyboard if I don't know the view currently viewing?


Solution

  • Add a category to UIResponder: Get the current first responder without using a private API

    static __weak id currentFirstResponder;
    
    @implementation UIResponder (FirstResponder)
    
    +(id)currentFirstResponder {
        currentFirstResponder = nil;
        [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
        return currentFirstResponder;
    }
    
    -(void)findFirstResponder:(id)sender {
        currentFirstResponder = self;
    }
    
    +(void)hideKeyboard {
        id firstResponder = [UIResponder currentFirstResponder];
        if([firstResponder respondsToSelector:@selector(endEditing:)]) {
            [firstResponder endEditing:YES];
        }
    }
    
    @end
    

    Import the category and do below in your action to hide keyboard:

    if([[UIResponder currentFirstResponder] respondsToSelector:@selector(endEditing:)]) {
        [[UIResponder currentFirstResponder] endEditing:YES];
    } 
    

    By this solution, you do not need to know the view currently viewing. Just get the current first responder and call endEdition:. For when editable view become editing, it will become first responder.

    EDIT:

    With Vyachaslav Gerchicov's suggestion, I add hideKeyboard method in the category. And just call [UIResponder hideKeyboard];.