UIKeyboardBoundsUserInfoKey is deprecated, what should I use instead?

I am working on an iPad application using 3.2 sdk. I am dealing with getting a keyboard size so that my text fields do not hide behind it.

I get a warning in Xcode -> UIKeyboardBoundsUserInfoKey is out of date, what should I use instead to not get this warning?

+49
ios objective-c iphone uikeyboard
May 11 '10 at 12:28 a.m.
source share
8 answers

I played with a previously proposed solution, but still had problems. Here is what I came up with instead:

- (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]; } 
+87
May 29 '10 at 8:21 a.m.
source share

From the documentation for UIKeyboardBoundsUserInfoKey :

A key for an NSValue object containing a CGRect that identifies the rectangle of the keyboard borders in window coordinates. This value is enough to get the size of the keyboard. If you want to get the beginning of the keyboard on the screen (before or after the animation), use the values ​​obtained from the user information dictionary through the constants UIKeyboardCenterBeginUserInfoKey or UIKeyboardCenterEndUserInfoKey. Instead, use the UIKeyboardFrameBeginUserInfoKey or UIKeyboardFrameEndUserInfoKey key.

Apple recommends introducing such a convenient procedure (which can be implemented as an addition to the UIScreen category):

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

to restore the keyboard frame size properties adjusted below the window.

I used a different approach, which includes checking device orientation:

 CGRect _keyboardEndFrame; [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame]; CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width; 
+55
May 11 '10 at a.m.
source share

You just use this code:

 //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]; 
+9
Dec 02 '10 at
source share

The following code fixes a problem in the Jay answer , which assumes that UIKeyboardWillShowNotification will not start again when the keyboard is already present.

When typing with a Japanese / Chinese keyboard, iOS launches an additional UIKeyboardWillShowNotification with a new keyboard frame, even if the keyboard is already present, which leads to the fact that the height of self.textView reduced a second time in the source code.

This reduces self.textView almost zero. After that, it becomes impossible to repair this problem, since we expect only one UIKeyboardWillHideNotification at the next keyboard dismissal.

Instead of subtracting / adding height in self.textView depending on whether the keyboard is displayed or hidden, as in the source code, the following code simply calculates the maximum possible height for self.textView after subtracting the height of the keyboard on the screen.

It is assumed that self.textView should fill the entire view controller view, and there is no other self.textView view that should be visible.

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

Also, be sure to register keyboard notifications in 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]; } 

About splitting resize code into two parts

The reason that the textView resizing code is split into two parts ( resizeTextViewWithKeyboardNotification: and resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: is to fix another problem when the keyboard is saved by pressing from one view controller to another (see How to determine iOS keyboard when it stays between controllers? ).

Since the keyboard is already present before pressing the view controller, there are no additional keyboard notifications generated by iOS, and therefore there is no way to resize the textView based on these keyboard notifications.

The above code (as well as the source code) that resizes self.textView will only work when the keyboard is displayed after the image has been loaded.

My solution is to create a singleton that stores the last coordinates of the keyboard, and in - viewDidAppear: viewController will call:

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // Resize the view if there 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 is my singleton. Ideally, we should call it in - viewWillAppear: however, in my experience (at least on iOS 6), the convertRect:fromView: method that we need to use in resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: incorrectly converts the keyboard frame to coordinates The view in front of the view is fully visible.

+3
Oct 18 '12 at 11:21
source share

Just use the keys UIKeyboardFrameBeginUserInfoKey or UIKeyboardFrameEndUserInfoKey instead of UIKeyboardBoundsUserInfoKey

+2
Oct 05
source share

@Jason, you code if fine except one point.

At the moment, you really aren’t animating anything, and the show is just pop to a new size. height.

You must specify the state from which you want to animate. Animation is a kind of (from state) β†’ (to state) thing.

Fortunately, there is a very convenient way to specify the current state of a view as (from state).

 [UIView setAnimationBeginsFromCurrentState:YES]; 

If you add this line right after beginAnimations: context: your code works fine.

+1
Jun 22 2018-10-06T00:
source share
 - (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; } 
+1
Mar 07 2018-11-11T00:
source share
0
Jan 18 2018-12-18T00:
source share



All Articles