简体   繁体   中英

How to calculate keyboard height in iOS?

I know that this question is asked many times, but I can not figure out where am I making mistake. In simple words I can not implement it properly.

I have App which has to work on iPhone and iPad (in portrait orientation only). I have a subclassed UITextField . I need to move it up when it is hidden by keyboard during the edit. I can not set it properly, because the calculation of the size of the keyboard is done after it enters in the edit mode.

I know that I need following steps:

  1. Register observer
  2. Have routine that calculates Keyboard rectangle from which I can take height
  3. Have 2 events on show and hide of the keyboard to make offset of my custom text field.

Please tell me where I am wrong.

My code is:

Register observer:

- (id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super initWithCoder:aDecoder]) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardDidShowNotification object:nil];
        _leftInlineImage = NO;
    }
    return self;
}

Calculating keyboard height:

- (void)keyboardWillChange:(NSNotification *)notification {
    NSDictionary* d = [notification userInfo];
    CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    r = [self.superview convertRect:r fromView:nil];
    _keyboardHeight = r.size.height;
}

Show/hide keyboard:

/* Move keyboard */
-(void)showKeyboardWithMove {

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    ////CGFloat screenWidth = screenRect.size.width;
    CGFloat screenHeight = screenRect.size.height;

    //_keyboardHeight = KEYBOARD_HEIGHT;

    if (self.frame.origin.y + self.frame.size.height > screenHeight - _keyboardHeight) {
        double offset = screenHeight - _keyboardHeight - self.frame.origin.y - self.frame.size.height;
        CGRect rect = CGRectMake(0, offset, self.superview.frame.size.width, self.superview.frame.size.height);

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.3];

        self.superview.frame = rect;

        [UIView commitAnimations];
    }

}

-(void)hideKeyboardWithMove {

    CGRect rect = CGRectMake(0, 0, self.superview.frame.size.width, self.superview.frame.size.height);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    self.superview.frame = rect;

    [UIView commitAnimations];

}

The calculation is made before and my height is 0. All this is done in the subclass of the UITextField .

Add an observer of UIKeyboardWillChangeFrameNotification to the viewDidLoad ;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameDidChange:) name:UIKeyboardWillChangeFrameNotification object:nil];

This method will help you :

- (void)keyboardFrameDidChange:(NSNotification *)notification
{
    CGRect keyboardEndFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    UIViewAnimationCurve animationCurve = [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    NSTimeInterval animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] integerValue];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];

    CGRect newFrame = self.view.frame;
    CGRect keyboardFrameEnd = [self.view convertRect:keyboardEndFrame toView:nil];
    CGRect keyboardFrameBegin = [self.view convertRect:keyboardBeginFrame toView:nil];

    newFrame.origin.y -= (keyboardFrameBegin.origin.y - keyboardFrameEnd.origin.y);
    self.view.frame = newFrame;

    [UIView commitAnimations];
}

that gives you back the height of the keyboard.

NSNotification * note = // ... the notification you receive via UIKeyboardWillShowNotification
id _obj = [note.userInfo valueForKey:@"UIKeyboardBoundsUserInfoKey"];
CGRect _keyboardBound = CGRectNull;
if ([_obj respondsToSelector:@selector(getValue:)]) [_obj getValue:&_keyboardBound];

the _keyboardBound will have the correct size.


NOTE: that is not a full implementation to handle the keyboard's appearance, if you need the complex idea, please check my complete and accepted answer here (stackoverflow.com internal link) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM