iOS Dismiss Keyboard on View Change
-
14-11-2019 - |
Pergunta
I have a view-based application, and in one of the subviews there is a UIScrollView. I have written handlers to adjust the size of the scroll view when the keyboard appears and disappears. I would like the keyboard to be dismissed when the user leaves the view, so I call [currentField resignFirstResponder]
in viewWillDisappear
. This dismisses the keyboard, but does not call the handler to resize the scroll view (when I call the same code in other places, it does). Any suggestions?
EDIT: These are the handlers that I use:
-(void) keyboardWasShown:(NSNotification*) notification
{
if(keyboardShown)
return;
NSDictionary* info=[notification userInfo];
NSValue* value=[info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGSize keyboardSize=[value CGRectValue].size;
CGRect viewFrame=[scrollView frame];
viewFrame.size.height-=keyboardSize.height;
scrollView.frame=viewFrame;
keyboardShown=YES;
}
-(void) keyboardWasHidden:(NSNotification*) notification
{
NSDictionary* info=[notification userInfo];
NSValue* value=[info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGSize keyboardSize=[value CGRectValue].size;
CGRect viewFrame=[scrollView frame];
viewFrame.size.height+=keyboardSize.height;
scrollView.frame=viewFrame;
keyboardShown=NO;
}
When I call [currentField resignFirstResponder]
anywhere else, it calls the handler without problems.
Solução
So you were being removed as observer before UIKeyboardDidHideNotification
was posted, glad I could help. But observing the UIKeyboardWillHideNotification
and UIKeyboardWillShowNotification
is probably enough for your reaction to the keyboard. The keyboard notifications have a user info key UIKeyboardAnimationDurationUserInfoKey
which you can use to animate your frame adjustments with the keyboard animations. This avoids the 'clunk' feeling your views will have if you don't animate them to new positions. Here is a quick example of what you can do:
-(void)keyboardWillNotificationTarget:(NSNotification *)note{
// Find current keyboard origin Y
NSValue *keyboardCurrentFrameValue = [note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGFloat currentOriginY = keyboardCurrentFrameValue.CGRectValue.origin.y;
// Find keyboard Y that will be
NSValue *keyboardNewFrameValue = [note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGFloat newOriginY = keyboardNewFrameValue.CGRectValue.origin.y;
// Calculate new frame for scrollView
CGFloat heightChangeForScrollView = newOriginY - currentOriginY;
CGRect svFrame = scrollView.frame;
svFrame.size.height += heightChangeForScrollView;
// Find duration of animation
NSNumber *animationDurationNumber = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
CGFloat animationDuration = animationDurationNumber.floatValue;
// Animate scrollView with keyboard
[UIView animateWithDuration:animationDuration animations:^{
scrollView.frame = svFrame;
}];
}
Now you simply add this method as the target for both notifications:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillNotificationTarget:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillNotificationTarget:) name:UIKeyboardWillHideNotification object:nil];