转载:http://blog.unieagle.net/2012/06/04/ios开发中的键盘高度变化处理/
在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]; }