键盘“WillShow”和“WillHide”与旋转

我有一个视图控制器监听UIKeyboardWillShowNotification和UIKeyboardWillHideNotification。 这些通知的处理程序会调整视图的各个部分,这是标准过程。

以下代码用于从屏幕坐标转换键盘矩形:

CGRect keyboardBounds = [self.view convertRect:[keyboardBoundsValue CGRectValue] fromView:nil]; 

再次,标准程序。 不幸的是,这种转换失败的危急情况。 查看在部署键盘时将iPhone从纵向旋转到横向时发生的情况:

1)iOS自动触发UIKeyboardWillHideNotification ; self.interfaceOrientation被报告为肖像 ; keyboardBounds.height是216.0这是有道理的 。 为什么? 因为在视图切换到横向模式之前,通知处理程序有机会“清理”。

2)iOS自动触发UIKeyboardWillShowNotification ; self.interfaceOrientation被报告为肖像 ; keyboardBounds.height是480.0这没有任何意义 。 为什么不? 因为通知处理程序将要做的工作,认为键盘的高度是480.0!

苹果是不是把这个球弄丢了,还是我做错了什么?

请注意,代替UIKeyboard听ShowNotification不是一个有效的解决scheme,因为它显着降低了用户体验。 为什么? 因为在键盘部署animation发生后,对视图所做的更改animation效果非常糟糕。

有没有人设法让自动旋转完美的键盘部署? 苹果已经完全忽视了混乱的爆发。 >:|

也许有点晚了,但我碰到同样的问题,并有一个很好的解决scheme,避免任何forms的工作(除非苹果改变的东西)

基本上,当通知中心调用UIKeyboardWillShowNotification (或任何其他通知)的方法时,它为UIKeyboardFrameBeginUserInfoKey提供的框架是在窗口的上下文中,而不是您的视图。 问题在于,无论设备的方向如何,窗口坐标系始终处于纵向,因此您发现宽度和高度是错误的。

如果你想避免你的工作,只需将矩形转换为你的视图的坐标系(根据方向改变)。 为此,请执行以下操作:

 - (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 */ ...... } 

希望这应该是你以后:)

最近我写了一篇关于你所描述的确切问题的博客文章,以及如何用简短而优雅的方式解决这个问题。 以下是post的链接: 在键盘和附加视图之间同步旋转animation

如果您不想深入博客文章中描述的长篇解释,请使用代码示例进行简短描述:

基本原则是使用每个人都使用的相同方法 – 观察键盘通知以上下animation化所连接的视图。 但除此之外,由于接口方向更改而导致键盘通知被触发时,您必须取消这些animation。

不带animation取消的旋转示例自定义界面方向更改:

在界面方向更改上带有animation取消的旋转示例:

 - (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; } } 

这个答案也发布在类似的问题: UIView上面的键盘类似于iMessage应用程序

我遇到了同样的问题。 iOS给了我不正确的键盘宽度/高度。 我在keyboardDidShow处理程序中使用了以下内容:

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

而对于iPad的纵向和横向模式,我分别得到了:

 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} 

猜测键盘的宽度应该大于高度(是的,我很天真),我做了一个解决方法,如下所示:

 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; } 

那么,请尝试查看键盘宽度。 如果这是你所期望的价值,那么我认为这些价值是简单的切换;)。 480作为进入风景的键盘宽度是有意义的,这是什么给了我这种预感。

如果失败,则分别存储纵向和横向矩形。 他们是有据可查的 ;)

我知道这是一个非常非常迟的答复。 现在只有我遇到这种情况,find了没有答案的问题。 所以我想我会分享我的解决scheme。 还有其他更好的方法,但是下面的方法也可以解决这个问题。

我使用的KBKeyboardHandler来自: UITextField:当键盘出现时移动视图

我只是改变了我的代表如下:

 - (void)keyboardSizeChanged:(CGSize)delta { CGRect frame = self.view.frame; UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; switch (interfaceOrientation) { case UIInterfaceOrientationPortrait: frame.origin.y-=delta.height; break; case UIInterfaceOrientationPortraitUpsideDown: frame.origin.y+=delta.height; break; case UIInterfaceOrientationLandscapeLeft: frame.origin.x-=delta.height; break; case UIInterfaceOrientationLandscapeRight: frame.origin.x+=delta.height; break; default: break; } self.view.frame = frame; } 

它工作正常。

这是我的解决方法:

 CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; float keyboardHeight = self.interfaceOrientation == UIInterfaceOrientationPortrait ? keyboardSize.height : keyboardSize.width; 

希望这可以帮助 :)

我使用下面的代码来获得适用于所有旋转的键盘的大小

 NSDictionary *info = [aNotification userInfo]; if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) kbHeight = [[NSNumber numberWithFloat:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.width] floatValue]; else kbHeight = [[NSNumber numberWithFloat:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height] floatValue]; NSLog(@"keyboard height = %F",kbHeight); 

然后,我使用状态栏方向(在iPad的第一个启动案例中工作)testing方向,并将视图向相对方向移动,以便为键盘腾出空间。 这完美地工作,如果键盘是可见的,那么它重新定位到旋转的正确位置。

 UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (orientation == UIDeviceOrientationPortrait) { NSLog(@"Orientation: portrait"); self.originalCenter = self.view.center; self.view.center = CGPointMake(self.originalCenter.x, self.originalCenter.y-kbHeight); } if (orientation == UIDeviceOrientationPortraitUpsideDown) { NSLog(@"Orientation: portrait upside down"); self.originalCenter = self.view.center; self.view.center = CGPointMake(self.originalCenter.x, self.originalCenter.y+kbHeight); } if (orientation == UIDeviceOrientationLandscapeLeft) { NSLog(@"Orientation: landscape left"); self.originalCenter = self.view.center; self.view.center = CGPointMake(self.originalCenter.x+kbHeight,self.originalCenter.y); } if (orientation == UIDeviceOrientationLandscapeRight) { NSLog(@"Orientation: landscape right"); self.originalCenter = self.view.center; self.view.center = CGPointMake(self.originalCenter.x-kbHeight,self.originalCenter.y); } 

当键盘消失或通过textFileDidEndEditing函数时,您可以将视图返回到原始位置。