UIKeyboardBoundsUserInfoKey已弃用,请改用什么?
我正在使用3.2 sdk的iPad应用程序。 我正在处理获得键盘大小,以防止我的文本字段隐藏在它后面。
我在Xcode中得到一个警告 – > UIKeyboardBoundsUserInfoKey被弃用,我应该使用什么,而不是得到这个警告?
我玩过以前提供的解决scheme,但仍然有问题。 下面是我想到的:
- (void)keyboardWillShow:(NSNotification *)aNotification { [self moveTextViewForKeyboard:aNotification up:YES]; } - (void)keyboardWillHide:(NSNotification *)aNotification { [self moveTextViewForKeyboard:aNotification up:NO]; } - (void) moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{ NSDictionary* userInfo = [aNotification userInfo]; // Get animation info from userInfo NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardEndFrame; [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame]; // Animate up or down [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:animationDuration]; [UIView setAnimationCurve:animationCurve]; CGRect newFrame = textView.frame; CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil]; newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1); textView.frame = newFrame; [UIView commitAnimations]; }
从UIKeyboardBoundsUserInfoKey
的文档 :
包含CGRect的NSValue对象的关键字,用于在窗口坐标中标识键盘的边界矩形。 这个值足以获得键盘的大小。 如果要在屏幕上(animation之前或之后)获取键盘的原点,请使用通过UIKeyboardCenterBeginUserInfoKey或UIKeyboardCenterEndUserInfoKey常量从用户信息词典中获取的值。 改为使用UIKeyboardFrameBeginUserInfoKey或UIKeyboardFrameEndUserInfoKey键。
苹果build议实施这样的便利程序(这可以作为UIScreen
一个类别实现):
+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view { UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window]; return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil]; }
恢复窗口调整的键盘帧大小属性。
我采取了不同的方法,其中涉及检查设备方向:
CGRect _keyboardEndFrame; [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame]; CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;
您只需使用以下代码:
//NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey]; //instead of Upper line we can use either next line or nextest line. //NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey]; NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
以下代码修复了Jay的答案中的一个问题,该问题假定当键盘已经存在时, UIKeyboardWillShowNotification
将不会再次触发。
使用日文/中文键盘进行input时,即使键盘已经存在,iOS UIKeyboardWillShowNotification
使用新的键盘框架触发额外的UIKeyboardWillShowNotification
,导致self.textView
的高度在原始代码中第二次减less。
这减less了self.textView
几乎没有。 这样就不可能从这个问题中恢复,因为我们只会在下一次closures键盘时期待一个UIKeyboardWillHideNotification
。
self.textView
在self.textView
中减去/添加高度,取决于键盘是否在原始代码中显示/隐藏,下面的代码只是在减去屏幕上键盘的高度后计算self.textView
的最大可能高度。
这假定self.textView
是假设填充视图控制器的整个视图,没有其他子视图需要可见。
- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif { NSDictionary* userInfo = [notif userInfo]; NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardFrameInWindowsCoordinates; [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates]; [self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates withAnimationDuration:animationDuration animationCurve:animationCurve]; } - (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates withAnimationDuration:(NSTimeInterval)duration animationCurve:(UIViewAnimationCurve)curve { CGRect fullFrame = self.view.frame; CGRect keyboardFrameInViewCoordinates = [self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil]; // Frame of the keyboard that intersects with the view. When keyboard is // dismissed, the keyboard frame still has width/height, although the origin // keeps the keyboard out of the screen. CGRect keyboardFrameVisibleOnScreen = CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates); // Max frame availble for text view. Assign it to the full frame first CGRect newTextViewFrame = fullFrame; // Deduct the the height of any keyboard that's visible on screen from // the height of the text view newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height; if (duration) { [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:duration]; [UIView setAnimationCurve:curve]; } // Adjust the size of the text view to the new one self.textView.frame = newTextViewFrame; if (duration) { [UIView commitAnimations]; } }
另外,不要忘记在viewDidLoad中注册键盘通知:
- (void)viewDidLoad { [super viewDidLoad]; NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter]; [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil]; [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil]; }
关于将resize的代码分成两部分
resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
resize代码分为两部分( resizeTextViewWithKeyboardNotification:
和resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
是要解决键盘持续通过从一个视图控制器到另一个视图控制器时的问题(请参阅如何检测iOS键盘当它保持在控制器之间? )。
由于在推送视图控制器之前键盘已经存在,因此没有其他键盘通知由iOS生成,因此无法根据这些键盘通知来调整textView
的大小。
上面的代码(以及原始代码),调整self.textView
大小将因此只有在加载视图后显示键盘时才有效。
我的解决scheme是创build一个单一的存储最后的键盘坐标,并在viewController的onViewDidAppear:调用:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // Resize the view if there's any keyboard presence before this // Only call in viewDidAppear as we are unable to convertRect properly // before view is shown [self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame] withAnimationDuration:0 animationCurve:0]; }
UASKeyboard
是我的单身人士在这里。 理想情况下,我们应该在- viewWillAppear:
调用- viewWillAppear:
但是以我的经验(至less在iOS 6上),我们需要在resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
使用convertRect:fromView:
方法resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:
不正确地将键盘框架转换为视图视图完全可见之前的坐标。
只需使用UIKeyboardFrameBeginUserInfoKey
或UIKeyboardFrameEndUserInfoKey
键代替UIKeyboardBoundsUserInfoKey
@Jason,除了一分之外,你还可以编码。
目前你并没有实际制作任何animation,视图只是“popup”到新的尺寸。
你必须指定一个animation的状态。 animation是一种(从状态) – >(到状态)的东西。
幸运的是,有一个非常方便的方法来指定视图的当前状态(来自状态)。
[UIView setAnimationBeginsFromCurrentState:YES];
如果您在beginAnimations之后添加该行:context:您的代码完美工作。
- (CGSize)keyboardSize:(NSNotification *)aNotification { NSDictionary *info = [aNotification userInfo]; NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey]; UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; CGSize keyboardSize; if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) { _screenOrientation = orientation; if (UIDeviceOrientationIsPortrait(orientation)) { keyboardSize = [beginValue CGRectValue].size; } else { keyboardSize.height = [beginValue CGRectValue].size.width; keyboardSize.width = [beginValue CGRectValue].size.height; } } else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) { // We didn't rotate if (_screenOrientation == orientation) { if (UIDeviceOrientationIsPortrait(orientation)) { keyboardSize = [beginValue CGRectValue].size; } else { keyboardSize.height = [beginValue CGRectValue].size.width; keyboardSize.width = [beginValue CGRectValue].size.height; } // We rotated } else if (UIDeviceOrientationIsPortrait(orientation)) { keyboardSize.height = [beginValue CGRectValue].size.width; keyboardSize.width = [beginValue CGRectValue].size.height; } else { keyboardSize = [beginValue CGRectValue].size; } } return keyboardSize; }