3

I read many post here about this topic, but I wasn't able to find an answer to my question, so, hope you won't be bored about another UIKeyboard post :-)

In my view controller's implementation I added self as an observer for the two notifications UIKeyboardWillShowNotification and UIKeyboardWillHideNotification, passing the selectors keyboardWillShow: and keyboardWillHide: to handle to notifications. As I touch a UITextField, the keyboardWillShow: method is called but when I press a "Done" button (which dismisses the keyboard) the keyboardWillHide: method is not called.

Really, I'd like to make my UITextField show a keyboard with the "hide button" on the bottom right of the keyboard, but I wasn't able to find the right keyboard type. Maybe I need to set the textfield retuntype to "...Done". In that way I saw that "return" key turns to "done".

So I set a toolbar to be my UITextField's inputAccessoryView, so now I can show a standard keyboard with a tool bar above with the "Done" button. As a user touches that button, I hide the keyboard with the resignFirstResponder method.

The strange thing is that when I call resignFirstResponder, the UIKeyboardWillHideNotification isn't posted; at least the keyboardWillHide: method is not called.

What do you suggest to me? I really wanted to display a keyboard with the small button with the down arrow to hide the keyboard, but also this solution could be right, but I'd like to resize the view and to do this I need to observer UIKeyboardWillHideNotification.

Thank you very much for help...

(ADDED:)

In viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:[[self view] window]];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:[[self view] window]];    

I took these declarations from one of "yours" post :-) But the willShow works...

The action of the "Done" button that's in the UIToolbar that's assigned to be the inputAccessoryView of my text field is:

-(void)keyboardDone {
    [msgTextField resignFirstResponder];

CLOSED: OK! When a developer is stupid... it is stupid :-) :-)

This is my corrected willHide method:

-(void)keyboardWillHide:(NSNotification*)n {
    NSDictionary* userInfo;
    CGSize keyboardSize;
    CGRect viewFrame;

    /* This was the bad guy :) I forgot to delete it
     * after I previously copied the willShow method that
     * checks if keyboard is already shown (if so returns).
     *
     * if( keyboardIsShown )
     *   return;
     */
    userInfo = [n userInfo];
    keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    viewFrame = [[self scrollView] frame];
    viewFrame.size.height += ( keyboardSize.height - TABBAR_HEIGHT );

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.5];
    [[self scrollView] setFrame:viewFrame];
    [UIView commitAnimations];

    keyboardIsShown = NO;
    NSLog(@"HIDE\n");
}

First of all I'd like to thank you all for this useless work in helping me. I'd like to give you some points, so I'll try to rise a "interest point" for each answer, but I need to choose the right one... hard part... :-)

Excuse me again... I really didn't see the if() statement...

Altair Jones
  • 834
  • 1
  • 7
  • 20

5 Answers5

3

If you read the documents for UIWindow it says that the notification object for these notifications is nil. You are passing self.view.window in as the object to the addObserver:selector:name:object: method. Try passing nil instead:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil;
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • @AltairJones So you tried passing `nil` as the `object` parameter, and yet the same exact problem is occurring, i.e. your `keyboardWillShow:` method is called but the keyboard hides without your `keyboardWillHide:` method being called? – Carl Veazey Sep 07 '12 at 22:00
  • I chosed this one as a right answer because it gives some kind of "scholar" information about how SDK works :-) – Altair Jones Sep 07 '12 at 22:23
2

It's important to note that when the user hides the software keyboard via the hide button, the hide methods aren't called. The show methods are called again, but the keyboard is nearly off screen except for the home row toolbar.

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
1

Check, if keyboardDone really gets called (i.e. with NSLog(@"%@", @"keyboard done called");). If its get called, but resignFirstResponder does not help dismissing the keyboard, then try this:

[self.view endEditing:YES];

Please also provide your keyboardWillHide: method.

  • The keyboardDone is called, the keyboard hides. The keyboardWillHide is not called, I use that function to resize using the notification object to get the keyboard size. – Altair Jones Sep 07 '12 at 21:48
  • @AltairJones use the `userInfo` dictionary of the notification to get that information, not the `object`. See: http://stackoverflow.com/questions/9135248/logic-for-moving-text-field-above-keyboard-on-tap/9136698#9136698 – Carl Veazey Sep 07 '12 at 22:04
  • How does your `keyboardWillHide:` look like... Please try this, to check, wether your `keyboardWillHide:` is added correctly: `if ([self respondsToSelector:@selector(keyboardWillHide:)])` `{` `NSlog(@"%@", @"Method declared correctly");` `}` – Sascha Manuel Hameister Sep 07 '12 at 22:06
1

To set the keyboard up so that it has a "Done" button, do this:

1) Setup your view controller so that it implements the UITextFieldDelegate. For Example:

#import <UIKit/UIKit.h>

@interface TX_ViewController : UIViewController <UITextFieldDelegate>

@property (nonatomic, retain) IBOutlet UITextField *textField;

@end

2) In your view controllers implementation file, use the following code to setup the keyboard:

- (void)viewDidLoad
{
    [self.textField setDelegate:self];
    [self.textField setReturnKeyType:UIReturnKeyDone];
    [self.textField addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

3) And if you wish to do something when the DONE button is pressed, simply add the following function to your view controller's implementation file:

- (IBAction)textFieldFinished:(id)sender
{
    [sender resignFirstResponder];
}

Also, if you are using Interface builder to create your interfaces, don't forget to setup your IBOutlet reference for the TextField; otherwise, your class won't receive the messages from the XIB.

I set this up in a sample application just to see if it works and it did perform in the way you wish for your application to perform.

Anil
  • 2,539
  • 6
  • 33
  • 42
  • Thank you very much. So... there is someone that do not use IB to create views? How do you correctly design the layout?? – Altair Jones Sep 07 '12 at 22:34
  • I'm still a newbie when it comes to creating views programmatically. I presently use IB to create views. I have worked with developers that choose to do this programmatically, but it hurts my head when I have to read their code because it never made sense to me why a developer would want to spend extra time writing the code to create a view when IB does all of that for you. I'm sure there is a positive reason for doing it programmitically, I have yet to have my a-ha moment on this topic. I hope that my answer helped you resolve your issue though. :) – Anil Sep 07 '12 at 22:41
0

Swift $

NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

func keyboardWillHide(notification: NSNotification){
     print("keyboardWillHide")
}
ZAFAR007
  • 3,049
  • 1
  • 34
  • 45