Question

Is there some way to get UIKeyboard size programmatically. 216.0f height and 162.0f height in landscape.

Following seem to be deprecated. Is there some way that works without any warning in both 3.0 iPhone OS SDK and 4.0 iPhone OS SDK to do this..

CGSize keyBoardSize = [[[note userInfo]
                        objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size;
Was it helpful?

Solution

You can get the keyboard size from the userInfo dictionary using the UIKeyboardFrameBeginUserInfoKey and the UIKeyboardFrameEndUserInfoKey instead.

These two keys return a NSValue instance containing a CGRect that holds the position and size of the keyboard at both the start and end points of the keyboard's show/hide animation.

Edit:

To clarify, the userInfo dictionary comes from an NSNotification instance. It's passed to your method that you register with an observer. For example,

- (void)someMethodWhereYouSetUpYourObserver
{
    // This could be in an init method.
    [[NSNotificationCenter defaultCenter] addObserver:self 
                    selector:@selector(myNotificationMethod:) 
                    name:UIKeyboardDidShowNotification 
                    object:nil];
}

- (void)myNotificationMethod:(NSNotification*)notification
{
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
}

Edit 2:

Also, please don't forget to remove yourself as an observer in your dealloc method! This is to avoid a crash that would occur when the notification center tries to notify your object after its been freed.

OTHER TIPS

You should use the UIKeyboardWillChangeFrameNotification instead, because some international keyboards, like the Chinese keyboard, will change frames during use. Also make sure to convert the CGRect into the proper view, for landscape use.

//some method like viewDidLoad, where you set up your observer.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];

- (void)keyboardWillChange:(NSNotification *)notification {
    CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; //this is it!
}

Here's how I finally made works. I combined suggestions and codes from different answers. Features: dismissing keyboard, moving text fields above keyboard while editing and setting "Next" and "Done" keyboard return type.REPLACE "..." with more fields

static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;

@interface ViewController () <UITextFieldDelegate>
 @property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
  .....// some other text fields
 @property (weak, nonatomic) IBOutlet UITextField *emailTXT;
@end

@implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(tapScreen:)];// outside textfields

[self.view addGestureRecognizer:tapGesture];

// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];

// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];

// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self     selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self      selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}

// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
  if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
  ...
  if([self.emailTXT isFirstResponder])[self.emailTXT  resignFirstResponder];

  }
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
   if(textField.returnKeyType==UIReturnKeyNext) {
     // find the text field with next tag
     UIView *next = [[textField superview] viewWithTag:textField.tag+1];
     [next becomeFirstResponder];
   } else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
    [textField resignFirstResponder];
 }
return YES;
}

// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
   CGRect viewFrame = self.view.frame;
   CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
   CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
   CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//

   CGFloat keyboardHeight = keyboardSize.height;

   BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
  if (isTextFieldHidden) {
    animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
    viewFrame.origin.y -= animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
  return YES;
}

-(void) restoreViewFrameOrigionYToZero{
  CGRect viewFrame = self.view.frame;
  if (viewFrame.origin.y != 0) {
    viewFrame.origin.y = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
}

-(void)keyboardDidShow:(NSNotification*)aNotification{
   NSDictionary* info = [aNotification userInfo];
   keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
 }

-(void)keyboardDidHide:(NSNotification*)aNotification{
   [self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its  zero origin
}
@end

On swift 4

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(getInfo(notif:)), name: .UIKeyboardDidShow , object: nil)
}

and then:

@objc func getInfo(notif: NSNotification) -> Void {  
    guard let userInfo = notif.userInfo else {return}

    if let myData = userInfo["UIKeyboardFrameBeginUserInfoKey"] as? CGRect {
        print(myData.width)
        print(myData.height)
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top