iOS开发中的键盘高度变化处理

By | 2012 年 6 月 4 日

在ios开发中,键盘很常用。在sdk版本5.0以前,键盘高度是固定值216px;5.0出来以后,键盘高度会随着键盘语言变化(中文要高些),在这种情况下一般而言对于界面需要重新布局。方法是利用NSNotificationCenter。

UIKeyboardWillShowNotification;
UIKeyboardDidShowNotification; 
UIKeyboardWillHideNotification; 
UIKeyboardDidHideNotification;

这几个notification是5.0sdk之前就有的,顾名思义就知道意思了。

UIKeyboardWillChangeFrameNotification  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
UIKeyboardDidChangeFrameNotification   __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);

这两个是sdk 5.0以后出来的,用来处理键盘高度的变化。

使用方法是:首先在notification注册观察者,比如:

if([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

当键盘高度将要变化时,就会收到通知,在通知的参数中可以得到键盘目前的高度和变化的目标高度,比如:

-(void)keyboardWillChangeFrame:(NSNotification*)notif{
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_2  
    NSValue *keyboardBoundsValue = [[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];  
#else  
    NSValue *keyboardBoundsValue = [[notif userInfo] objectForKey:UIKeyboardBoundsUserInfoKey];  
#endif
    CGRect keyboardEndRect = [keyboardBoundsValue CGRectValue];
    CGRect inputFrame = self.feedBackTextView.frame;
    //kb 216 vs textFrame 185
    float delta = keyboardEndRect.size.height - 216;
    float originalHeight = inputFrame.size.height;
    inputFrame.size.height = 185 - delta;
    if (inputFrame.size.height != originalHeight) {
        self.feedBackTextView.frame = inputFrame;
        self.feedBackBackgroundView.frame = inputFrame;
    }
}

另外一些从notification.userInfo中可以取得的key如下:

UIKeyboardFrameBeginUserInfoKey        // NSValue of CGRect
UIKeyboardFrameEndUserInfoKey          // NSValue of CGRect
UIKeyboardAnimationDurationUserInfoKey // NSNumber of double
UIKeyboardAnimationCurveUserInfoKey    // NSNumber of double



notif中userInfo的完整信息如下

keyboardChange:{
    UIKeyboardAnimationCurveUserInfoKey = 0;
    UIKeyboardAnimationDurationUserInfoKey = "0.25";
    UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {320, 216}}";
    UIKeyboardCenterBeginUserInfoKey = "NSPoint: {160, 372}";
    UIKeyboardCenterEndUserInfoKey = "NSPoint: {160, 588}";
    UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 264}, {320, 216}}";
    UIKeyboardFrameChangedByUserInteraction = 0;
    UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 480}, {320, 216}}";
}



下面是一个完整的解决方案,用户需要知道键盘高度的细致变化

#pragma mark Keyboard
-(void)keyboardWillChangeFrame:(NSNotification*)notif{
    NSLog(@"keyboardChange:%@",[notif userInfo]);
    float keyboadHeightBegin = 0;
    float keyboadHeightEnd = 0;
    float animationDuration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
    UIViewAnimationCurve animationCurve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue];
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_2
    CGRect keyboardBeginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGRect keyboardEndFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboadHeightBegin = 480 - keyboardBeginFrame.origin.y;
    keyboadHeightEnd = 480 - keyboardEndFrame.origin.y;
#else
    //these deprecated after iOS 3.2
    CGRect keyboardBounds = [[[notif userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue];
    CGPoint keybordCenterBegin = [[[notif userInfo] objectForKey:UIKeyboardCenterBeginUserInfoKey] CGPointValue];
    CGPoint keybordCenterEnd = [[[notif userInfo] objectForKey:UIKeyboardCenterEndUserInfoKey] CGPointValue];
    keyboadHeightBegin = 480 - (keybordCenterBegin.y - keyboardBounds.size.height / 2);
    keyboadHeightEnd = 480 - (keybordCenterEnd.y - keyboardBounds.size.height / 2);
#endif
    NSLog(@"keyboardHeightChangeFrom:%.2f,To:%.2f",keyboadHeightBegin,keyboadHeightEnd);
    return;
    if (keyboadHeightEnd > 0) {
        //keyboard show or change frame
        [UIView animateWithDuration:animationDuration delay:0 options:animationCurve animations:^{
        } completion:^(BOOL finished) {
        }];
    } else {
        //keyboard hide
    }
}
-(void)keyboardDidChangeFrame:(NSNotification*)notif{
    //info like willChangeFrame
}
-(void)keyboardWillShow:(NSNotification*)notif{
    //keyboard height will be 216, on iOS version older than 5.0
    [UIView animateWithDuration:0.3f animations:^{
        self.contentTableView.height = 480 - 44 - 216;
    }];
}
-(void)keyboardWillHide:(NSNotification*)notif{
    [UIView animateWithDuration:0.3f animations:^{
        self.contentTableView.height = 480 - 44 - 28;
    }];
}
-(void)registerKeyboardEvent{
    float systemVer = [[[UIDevice currentDevice] systemVersion] floatValue];
    if(systemVer >= 5.0) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
    } else {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
}
-(void)unregisterKeyboardEvent{
    if([[[UIDevice currentDevice] systemVersion] floatValue] > 5.0) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidChangeFrameNotification object:nil];
    } else {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];        
    }
}



下面这个解决方案就只考虑键盘出现和消失的处理

#pragma mark Keyboard
-(void)keyboardWillShow:(NSNotification*)notif{
    //keyboard height will be 216, on iOS version older than 5.0
    CGRect boxFrame = self.loginBoxView.frame;
    boxFrame.origin.y = 50;
    [UIView animateWithDuration:0.3f animations:^{
        self.loginBoxView.frame = boxFrame;
    }];
}
-(void)keyboardWillHide:(NSNotification*)notif{
    CGRect boxFrame = self.loginBoxView.frame;
    boxFrame.origin.y = 216;
    [UIView animateWithDuration:0.3f animations:^{
        self.loginBoxView.frame = boxFrame;
    }];
}
//在viewdidload中调用
-(void)registerKeyboardEvent{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
//在viewdidunload中调用
-(void)unregisterKeyboardEvent{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注