9

I have several UITextFields on my view (each inside a UITableViewCell). When the keyboard is fired from any of the textfields, I need to make some animations, mainly to change the frame of the UITableView. The same must happen when the keyboard will hide.

I have done the animation, so this is not the issue here.

Now, I use NSNotificationCenter to catch displaying/hiding of the keyboard:

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

The problem is when the keyboard is visible (a textfield is used) and I press inside another textfield. Usually for this thing keyboard will not hide, but will stay visible.

It works fine in iOS 4, but the problem comes in 3.1.3 (this is the version that I can test - possibly any version below 3.2). In versions older than 3.2 changing focus from a textfield directly to another textfield will fire the UIKeyboardWillHideNotification and UIKeyboardWillShowNotification.

Anyone knows a way to perform some animation when the keyboard will really show/hide, without the NSNotificationCenter?

Or how can I overcome this issue with versions lower than 3.2?

Thanks.

CristiC
  • 22,068
  • 12
  • 57
  • 89
  • 1
    A consideration: Almost everyone has upgraded to iOS 4 and those who haven't rarely download or update apps. One alternative is to switch to only supporting iOS 4 for new versions. Only bother with supporting both if your app is something on par of importance with a banking app or if you have some very special need to do so. – Peter DeWeese Jul 22 '11 at 19:51
  • @Peter: Agree with you. Only that the application is almost done. This small problem is not a real reason for me to support only iOS4 devices. – CristiC Jul 22 '11 at 19:55

3 Answers3

12

What you can do is set the textfield's/textview's delegate to the current view controller and implement these 2 methods

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

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    _keyboardWillHide = NO;
    return YES;    
}

After that in your method that get's triggered by the UIKeyboardWillHideNotification notification you can do something like

if (_keyboardWillHide) {
    // No other textfield/textview was selected so you can animate the tableView
    ...
}
_keyBoardWillHide = YES;

Let me know if that works for you.

Mihai Fratu
  • 7,579
  • 2
  • 37
  • 63
  • It worked, but with small changes: In your answer _keyBoardWillHide = YES; was in UIKeyboardWillHideNotification. I moved it everywhere I had [UITextField resignFirstResponder]; – CristiC Jul 27 '11 at 07:19
  • @shim One is for `UITextField`, the other for `UITextView`. – devios1 May 26 '15 at 02:14
2

Rather than avoid the notifications, you can set an NSTimer for 0.1 second to do your animations in one, and in the other, cancel the timer, that way if you get UIKeyboardWillHide and UIKeyboardWillShow both at once, you'll get a chance to cancel the timer. If you don't get both, the timer will reach zero and the animations will be carried out.

Alex Gosselin
  • 2,942
  • 21
  • 37
  • This is a good idea. But cannot be done since this will create a small gap (delay) between the animation of the UIKeyboard and my own animation. – CristiC Jul 22 '11 at 20:12
  • Do the notifications always fire in a predictable order? – Alex Gosselin Jul 22 '11 at 20:53
  • You could consider starting the animations in the WillHide method, then in the WillShow method check if the animation is started, and interrupt it. That way if there isn't a show, they'll be carried out, otherwise they'll get stopped before anything happens. Assuming both methods get called in rapid fire that is – Alex Gosselin Jul 23 '11 at 15:36
1

Consider using the UITextFieldDelegate protocol. The method textFieldShouldBeginEditing: will fire off before the notification and it will fire off everytime you go into the text field.

DShah
  • 9,768
  • 11
  • 71
  • 127
Steve Yung
  • 68
  • 5