Is there a way to prevent the keyboard from dismis

2019-01-14 11:55发布

问题:

I realize that this is the inverse of most posts, but I would like for the keyboard to remain up even if the 'keyboard down' button is pressed.

Specifically, I have a view with two UITextFields. With the following delegate method

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    return NO;
}

I am able to keep the keyboard up even if the user presses the Done button on the keyboard or taps anywhere else on the screen EXCEPT for that pesky keyboard down button on the bottom right of the keyboard.

I am using this view like a modal view (though the view is associated with a ViewController that gets pushed in a UINavigationController), so it really works best from a user perspective to keep the keyboard up all of the time. If anyone knows how to achieve this, please let me know! Thanks!

UPDATE Still no solution! When Done is pressed, it triggers textFieldShouldReturn, but when the Dismiss button is pressed, it triggers textFieldDidEndEditing. I cannot block the textField from ending editing or it never goes away. Somehow, I really want to have a method that detects the Dismiss button and ignores it. If you know a way, please enlighten me!

回答1:

There IS a way to do this. Because UIKeyboard subclasses UIWindow, the only thing big enough to get in UIKeyboard's way is another UIWindow.

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(coverKey) name:UIKeyboardDidShowNotification object:nil];
    [super viewDidLoad];
}

- (void)coverKey {
    CGRect r = [[UIScreen mainScreen] bounds];
    UIWindow *myWindow = [[UIWindow alloc] initWithFrame:CGRectMake(r.size.width - 50 , r.size.height - 50, 50, 50)];
    [myWindow setBackgroundColor:[UIColor clearColor]];
    [super.view addSubview:myWindow];
    [myWindow makeKeyAndVisible];
}

This works on iPhone apps. Haven't tried it with iPad. You may need to adjust the size of myWindow. Also, I didn't do any mem management on myWindow. So, consider doing that, too.



回答2:

I think I've found a good solution.

Add a BOOL as instance variable, let's call it shouldBeginCalledBeforeHand

Then implement the following methods:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    shouldBeginCalledBeforeHand = YES;
    return YES;
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    return shouldBeginCalledBeforeHand;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    shouldBeginCalledBeforeHand = NO;
}

As well as

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    return NO;
}

to prevent the keyboard from disappearing with the return button. The trick is, a focus switch from one textfield to another will trigger a textFieldShouldBeginEditing beforehand. If the dismiss keyboard button is pressed this doesn't happen. The flag is reset after a textfield has gotten focus.



回答3:

Old not perfect solution

I can only think of a not perfect solution. Listen for the notification UIKeyboardDidHideNotification and make of the textfields first responder again. This will move the keyboard out of sight and back again. You could keep record of which textfield was the last firstResponder by listening for UIKeyboardWillHideNotification and put focus on it in the didHide.

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(keyboardDidHide:) 
                                             name:UIKeyboardDidHideNotification
                                           object:nil];

...

- (void)keyboardDidHide:(id)sender
{
    [myTextField becomeFirstResponder];
}


回答4:

For iOS 9/10 and Swift 3, use this to create a rect which overlaps the "Hide keyboard" - Button

override func viewDidLoad() {
    NotificationCenter.default.addObserver(self, selector: #selector(coverKey), name: .UIKeyboardDidShow, object: nil)
}

func coverKey() {
    if let keyboardWindow = UIApplication.shared.windows.last {
        let r = UIScreen.main.bounds
        let myWindow = UIWindow.init(frame: CGRect(x: r.size.width - 50 , y: r.size.height - 50, width: 50, height: 50))
        myWindow.backgroundColor = UIColor.clear
        myWindow.isHidden = false
        keyboardWindow.addSubview(myWindow)
        keyboardWindow.bringSubview(toFront: myWindow)
    }
} 

Notice that this adds a sub view to the keyboard window instead of the main window



回答5:

Try adding a custom on top of the keyboard dismiss button so that the user won't be able to tab the dismiss button. I have used this method in one of my application.

- (void)addButtonToKeyboard {

    // create custom button
    UIButton *blockButton = [UIButton buttonWithType:UIButtonTypeCustom];
    blockButton.frame = //set the frame here, I don't remember the exact frame
    [blockButton setImage:[UIImage imageNamed:@"block_button.png"] forState:UIControlStateNormal];

    // locate keyboard view
    UIWindow *appWindows = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    UIView *keyboard;
    for (int i=0; i<[appWindows.subviews count]; i++) {
        keyboard = [appWindows.subviews objectAtIndex:i];
        // keyboard found, add the button
        if ([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES && [self.textField isFirstResponder]) {
            [keyboard addSubview:doneButton];

        }
    }

}


回答6:

Try this...

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
   return NO;
}

You can use notification as mentioned by Nick Weaver.