Keyboard "WillShow" and "WillHide" vs. Rotation Keyboard "WillShow" and "WillHide" vs. Rotation ios ios

Keyboard "WillShow" and "WillHide" vs. Rotation


Maybe a bit late, but I've just run into the same issue and have a nice solution for it that avoids any kind of work arounds (unless of course apple change things)

Basically, when the notification center calls your method for UIKeyboardWillShowNotification (or any of the other notifications), the frame that it gives you for UIKeyboardFrameBeginUserInfoKey is in context of the window, NOT your view. The problem with this, is that the windows coordinate system is always in portrait, regardless of the devices orientation, hence you're finding the width and height the wrong way round.

If you want to avoid your work around, simply convert the rectangle into the coordinate system of your view (which does change according to the orientation). To do this, do something like the following :

- (void) keyboardWillShow:(NSNotification *)aNotification{     CGRect keyboardFrame = [[[aNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];    CGRect convertedFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];    ......    /* Do whatever you want now with the new frame.     * The width and height will actually be correct now     */    ......}

Hopefully this should be what you're after :)


Recently I've wrote a blog post about this exact problem you've described and how to solve it with a short and elegant way. Here is the link to the post: Synchronizing rotation animation between the keyboard and the attached view

If you don't want to dive into the long explanation described in the blog post here is a short description with a code example:

The basic principle is to use the same method that everyone uses - observing keyboard notifications to animate the attached view up and down. But in addition to that, you have to cancel these animations when the keyboard notifications are fired as a consequence of interface orientation change.

Rotation example without animation cancellation custom on interface orientation change:

Rotation example with animation cancellation on interface orientation change:

- (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    [[NSNotificationCenter defaultCenter]            addObserver:self selector:@selector(adjustViewForKeyboardNotification:)            name:UIKeyboardWillShowNotification object:nil];    [[NSNotificationCenter defaultCenter]            addObserver:self selector:@selector(adjustViewForKeyboardNotification:)            name:UIKeyboardWillHideNotification object:nil];}- (void)viewDidDisappear:(BOOL)animated {    [super viewDidDisappear:animated];    [[NSNotificationCenter defaultCenter]            removeObserver:self name:UIKeyboardWillShowNotification object:nil];    [[NSNotificationCenter defaultCenter]            removeObserver:self name:UIKeyboardWillHideNotification object:nil];}- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];    self.animatingRotation = YES;}- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];    self.animatingRotation = NO;}- (void)adjustViewForKeyboardNotification:(NSNotification *)notification {    NSDictionary *notificationInfo = [notification userInfo];    // Get the end frame of the keyboard in screen coordinates.    CGRect finalKeyboardFrame = [[notificationInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];    // Convert the finalKeyboardFrame to view coordinates to take into account any rotation    // factors applied to the window’s contents as a result of interface orientation changes.    finalKeyboardFrame = [self.view convertRect:finalKeyboardFrame fromView:self.view.window];    // Calculate new position of the commentBar    CGRect commentBarFrame = self.commentBar.frame;    commentBarFrame.origin.y = finalKeyboardFrame.origin.y - commentBarFrame.size.height;    // Update tableView height.    CGRect tableViewFrame = self.tableView.frame;    tableViewFrame.size.height = commentBarFrame.origin.y;    if (!self.animatingRotation) {        // Get the animation curve and duration        UIViewAnimationCurve animationCurve = (UIViewAnimationCurve) [[notificationInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];        NSTimeInterval animationDuration = [[notificationInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];        // Animate view size synchronously with the appearance of the keyboard.         [UIView beginAnimations:nil context:nil];        [UIView setAnimationDuration:animationDuration];        [UIView setAnimationCurve:animationCurve];        [UIView setAnimationBeginsFromCurrentState:YES];        self.commentBar.frame = commentBarFrame;        self.tableView.frame = tableViewFrame;        [UIView commitAnimations];    } else {        self.commentBar.frame = commentBarFrame;        self.tableView.frame = tableViewFrame;    }}

This answer was also posted in similar question: UIView atop the Keyboard similar to iMessage App


I met the same problem. iOS gaves me incorrect width/height of the keyboard. I used the following snipped in a keyboardDidShow handler:

CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;CGSize keyboardSize2 = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;LogDbg(@"keyboard size: frameBegin=%@; frameEnd=%@", NSStringFromCGSize(keyboardSize), NSStringFromCGSize(keyboardSize2));

and for portrait and landscape modes of iPad I got respectively:

2012-06-14 04:09:49.734 -[LoginViewController keyboardDidShow:] 132 [DBG]:keyboard size: frameBegin={768, 264}; frameEnd={768, 264}2012-06-14 04:10:07.971 -[LoginViewController keyboardDidShow:] 132 [DBG]:keyboard size: frameBegin={352, 1024}; frameEnd={352, 1024}

Guessing that the width of the keyboard should be greater then the height (yep, i'm so naive) I made a workaround like following:

if (keyboardSize.width < keyboardSize.height){    // NOTE: fixing iOS bug: http://stackoverflow.com/questions/9746417/keyboard-willshow-and-willhide-vs-rotation    CGFloat height = keyboardSize.height;    keyboardSize.height = keyboardSize.width;    keyboardSize.width = height;}