IOS - 键盘处理
iOS 发布了很多关于屏幕上键盘的通知。下面列出了这些通知的简要解释:
注:键盘框架
这个框架被作为 iOS 键盘以开始和结束来发布的,它不会考虑设备的方向。我们需要 将 CGRect 值转换成一个关于坐标的值,后面会提到。
iOS5之前,iPhone上的键盘的高度是固定为216.0px高的,中文 汉字的选择框是悬浮的,所以不少应用都将此高度来标注键盘的高度。可是在iOS5中,键盘布局变了,尤其是中文输入时,中文汉字选择框就固定在键盘上方, 这样就使得原本与键盘紧密贴合的界面视图被中文汉字选择框给覆盖住了。一方面影响了界面的美观,另一方面,如果被覆盖的部分就是文本输入框的话,用户就无 法看到输入的内容了。因此这个问题就必须得解决了。
解决方法:
其实在一开始使用216.0px这个固定值来标注键盘的高度就是错误的。因为在iOS3.2以后的系统中,苹果就提供了键盘使用的api以及demo程序----"KeyboardAccessory"。
处理键盘事件的正确方法是这样的。(包括获取键盘的高度以及键盘弹出和消失动画的时间)
1)在要使用键盘的视图控制器中,接收键盘事件的通知:
- (void)viewDidLoad
{
[superviewDidLoad];
//键盘高度变化通知,ios5.0新增
#ifdef __IPHONE_5_0
float version = [[[UIDevicecurrentDevice] systemVersion] floatValue];
if (version >=5.0)
{
[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotificationobject:nil];
}
#endif
//键盘将要出现时的触发事件
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(keyboardWillShow:)name:UIKeyboardWillShowNotificationobject:nil];
//键盘将要消失时的触发事件
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(keyboardWillBeHidden:)name:UIKeyboardWillHideNotificationobject:nil];
}
2)然后添加键盘事件的处理代码:获取到当前keyboard的高度以及动画时间,然后对视图进行对应的操作即可。
-(void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
NSValue *value = [info objectForKey:@"UIKeyboardFrameEndUserInfoKey"];
CGSize keyboardSize = [value CGRectValue].size;//获取键盘的size值
NSLog(@"value %@ %f",value,keyboardSize.height);
//获取键盘出现的动画时间
NSValue *animationDurationValue = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];
CGFloat height =0 - keyboardSize.height +44;//加上导航栏的高度44
NSLog(@"height = %f",height);
NSTimeInterval animation = animationDuration;
//视图移动的动画开始
[UIViewbeginAnimations:nilcontext:nil];
[UIViewsetAnimationDuration:animation];
CGRect frame =CGRectMake(self.view.frame.origin.x, height, self.view.frame.size.width,self.view.frame.size.height);
self.view.frame = frame;
[UIViewcommitAnimations];
}
-(void)keyboardWillBeHidden:(NSNotification *)aNotification
{
NSDictionary *info = [aNotification userInfo];
NSValue *animationDurationValue = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];
NSTimeInterval animation = animationDuration;
[UIViewbeginAnimations:@"animal"context:nil];
[UIViewsetAnimationDuration:animation];
self.view.frame = [[UIScreenmainScreen] bounds];
[UIViewcommitAnimations];
}
duration在默认【中文拼音输入法】弹出时,不能正确获取duration,需要加一行代码修正:
duration = (duration > 0 ? duration: 0.25);//已知,IOS5.0.1里面键盘弹出动画的0.25S的,瑕疵:如果这里动画时间不是0.25就有可能动画不同步了
键盘处于显示状态的UIViewController被UINavigationController pop出去时,也会发出 UIKeyboardWillHideNotification通知,只不过这个键盘隐藏的轨迹是【从左到右的滑动】而不是从上到下的收起。所以,如果想在这个通知的响应代码里去调整UI(比如恢复底部工具条的origin.y使其始终居于底部),应该避免横向滑动键盘消失这种情况。可以通过以下响应代码来鉴别是否横向滑动导致键盘消失:
NSDictionary *info = [notification userInfo];
CGPoint kbEndOrigin = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin;
if(kbEndOrigtin.x > 0) {//横向滑动导致了键盘消失,不必调整UI
return;
}
//恢复UI显示
3)在dealloc方法里,移除键盘事件的通知:
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}