mutualmobile / MMDrawerController

A lightweight, easy to use, Side Drawer Navigation Controller
MIT License
6.76k stars 1.38k forks source link

How to make the keyboard hidden when drawer show? #267

Open zxhfirefox opened 10 years ago

zxhfirefox commented 10 years ago

If the center vc has some text filed in its view, when the the textfield is focused, and the user pan the center view to show drawer, the keyboard is hidden, and when the drawer is shown, the keyboard shown again.

How to hide the keyboard when the side vc is shown ?

pronebird commented 10 years ago

So the final solution I use is based on MMDrawerController subclass. It kills keyboard whenever drawer shows up using pan gesture or from code (e.g. from bar button handler).

The method call order here is important, keyboard should be dismissed before transition to sidebar, otherwise keyboard will ignore that request, dismiss itself and reappear after sidebar opened.

It will take more work for you to discover and save previous firstResponder and restore it when drawer closed, but I guess the best place to find firstResponder in view hierarchy is right before dismissKeyboard called.

@kcharwood may consider to include a flag to MMDrawerController to kill keyboard whenever it opens so people do not have to reimplement that in every app.

#import <MMDrawerController/MMDrawerController+Subclass.h>

@interface MYDrawerController : MMDrawerController
@end

@implementation MYDrawerController

- (void)panGestureCallback:(UIPanGestureRecognizer *)panGesture {
    [super panGestureCallback:panGesture];

    if(panGesture.state == UIGestureRecognizerStateRecognized) {
        [self dismissKeyboard];
    }
}

- (void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated completion:(void (^)(BOOL))completion {
    [self dismissKeyboard];

    [super openDrawerSide:drawerSide animated:animated completion:completion];
}

- (void)dismissKeyboard {
    [[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
}

@end
alexburkhay commented 10 years ago

thx.. very helpful). This should be noted in readme/documentation or like u said author can include this as a flag.

onmyway133 commented 9 years ago

The reason that the keyboard is hidden when sidebar is in progress (drag, moving) is that they toggle userInteractionEnabled

We can't use gestureCompletion like this because that the keyboard will show, then hide. Very unnatural

[self setGestureCompletionBlock:^(MMDrawerController *drawerController, UIGestureRecognizer *gesture) {
        [[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder)
                                                   to:nil from:nil forEvent:nil];
    }];

The solution is to get the UIPanGestureRecognizer

panGestureCallback is not public, so in your MMDrawerController subclass, you can do like this

- (void)viewDidLoad {
    [super viewDidLoad];

    // detect is a high order function that returns the first found object
    UIPanGestureRecognizer *panGR = [self.view.gestureRecognizers
                                     med_detect:^BOOL(UIGestureRecognizer *gr)
    {
        return [gr isKindOfClass:[UIPanGestureRecognizer class]];
    }];

    [panGR addTarget:self action:@selector(handlePanGR:)];
}

- (void)handlePanGR:(UIPanGestureRecognizer *)panGR {
    [[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
}
MartinSchultz commented 8 years ago

I've tried the solution from @pronebird but once I have the center view a text field, keyboard appears, I open the drawer, go back to the text field, the keyboard will not show up again and the input field is blocked. Any idea why?

blackyhn commented 8 years ago

override func viewDidLoad() { super.viewDidLoad() // detect is a high order function that returns the first found object if let cRecognisers = self.view.gestureRecognizers{ if let cRecogniser = cRecognisers.first{ cRecogniser.addTarget(self, action: "handlePanGR") } }

}

func handlePanGR() {
    UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
}
matrosovDev commented 8 years ago

@blackyhn dude, it works perfect thanks!