登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

iOS5 切换中文键盘时覆盖输入框的完美解决方案 [复制链接]

2012-11-22 13:45
北极熊爱企鹅 阅读:4837 评论:0 赞:0
Tag:  

众所周知,iOS5之前,iPhone上的键盘的高度是固定为216.0px高的,中文汉字的选择框是悬浮的,所以不少应用都将此高度来标注键盘的高度(包括米聊也是这么做的)。

  可是在iOS5中,键盘布局变了,尤其是中文输入时,中文汉字选择框就固定在键盘上方,这样就使得原本与键盘紧密贴合的界面视图被中文汉字选择框给覆盖住了。一方面影响了界面的美观,另一方面,如果被覆盖的部分就是文本输入框的话,用户就无法看到输入的内容了。因此这个问题就必须得解决了。

解决方法

  其实在一开始使用216.0px这个固定值来标注键盘的高度就是错误的。因为在iOS3.2以后的系统中,苹果就提供了键盘使用的API以及Demo程序——“KeyboardAccessory”。

  处理键盘事件的正确方法是这样的:(包括获取键盘的位置以及键盘弹出和消失动画的时间)

  1)在要使用键盘的视图控制器中(既viewDidLoad中),接收键盘事件的通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

// 键盘高度变化通知,ios5.0新增的 
#ifdef __IPHONE_5_0
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 5.0) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
}
#endif

2)然后添加键盘事件的处理代码:

    获取到当前keyboard的高度以及动画时间,然后对视图进行对应的操作即可。

#pragma mark -
#pragma mark Responding to keyboard events
- (void)keyboardWillShow:(NSNotification *)notification {
/*

     Reduce the size of the text view so that it's not obscured by the keyboard.

     Animate the resize so that it's in sync with the appearance of the keyboard.

     */

    NSDictionary *userInfo = [notification userInfo];

    // Get the origin of the keyboard when it's displayed.

    NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    // Get the top of the keyboard as the y coordinate of its origin in self's view's coordinate system. The bottom of the text view's frame should align with the top of the keyboard's final position.

    CGRect keyboardRect = [aValue CGRectValue];

    // Get the duration of the animation.

    NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];

    NSTimeInterval animationDuration;

    [animationDurationValue getValue:&animationDuration];

    

    // Animate the resize of the text view's frame in sync with the keyboard's appearance.

    [UIView animateWithDuration:animationDuration animations:^{

//此处的viewFooter即是你的输入框View

  //20为状态栏的高度

  self.viewFooter.frame = CGRectMake(viewFooter.frame.origin.x, keyboardRect.origin.y-20-viewFooter.frame.size.height,viewFooter.frame.size.width, viewFooter.frame.size.height);

    } completion:^(BOOL finished){

        

    }];

}


- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary* userInfo = [notification userInfo];

    NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    CGRect keyboardRect = [aValue CGRectValue];

    

    /*

     Restore the size of the text view (fill self's view).

     Animate the resize so that it's in sync with the disappearance of the keyboard.

     */

    [UIView animateWithDuration:0 animations:^{

        self.viewFooter.frame = CGRectMake(viewFooter.frame.origin.x, keyboardRect.origin.y-20-viewFooter.frame.size.height, viewFooter.frame.size.width, viewFooter.frame.size.height);

    } completion:^(BOOL finished){

        

    }];

}

  3)在视图控制器消除时(即viewDidUnload中),移除键盘事件的通知:

[[NSNotificationCenter defaultCenter] removeObserver:self];


背景:

  ios5之前,iphone上的键盘的高度是固定为216.0px高的,中文汉字的选择框是悬浮的,所以不少应用都将此高度来标注键盘的高度。

  可是在ios5中,键盘布局变了,尤其是中文输入时,中文汉字选择框就固定在键盘上方,这样就使得原本与键盘紧密贴合的界面视图被中文汉字选择框给覆盖住了。一方面影响了界面的美观,另一方面,如果被覆盖的部分就是文本输入框的话,用户就无法看到输入的内容了。因此这个问题就必须得解决了。

解决方法:

  其实在一开始使用216.0px这个固定值来标注键盘的高度就是错误的。因为在ios3.2以后的系统中,苹果就提供了键盘使用的api以及demo程序——“KeyboardAccessory”。

  处理键盘事件的正确方法是这样的:(包括获取键盘的高度以及键盘弹出和消失动画的时间)

1)在要使用键盘的视图控制器中,接收键盘事件的通知:

复制代码
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

// 键盘高度变化通知,ios5.0新增的
#ifdef __IPHONE_5_0
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 5.0) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil];
}
#endif
复制代码


  2)然后添加键盘事件的处理代码:

    获取到当前keyboard的高度以及动画时间,然后对视图进行对应的操作即可。

复制代码
#pragma mark -
#pragma mark Responding to keyboard events
- (void)keyboardWillShow:(NSNotification *)notification {

/*
Reduce the size of the text view so that it's not obscured by the keyboard.
Animate the resize so that it's in sync with the appearance of the keyboard.
*/

NSDictionary *userInfo = [notification userInfo];

// Get the origin of the keyboard when it's displayed.
NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

// Get the top of the keyboard as the y coordinate of its origin in self's view's coordinate system. The bottom of the text view's frame should align with the top of the keyboard's final position.
CGRect keyboardRect = [aValue CGRectValue];

// Get the duration of the animation.
NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];

// Animate the resize of the text view's frame in sync with the keyboard's appearance.
[self moveInputBarWithKeyboardHeight:keyboardRect.size.height withDuration:animationDuration];
}


- (void)keyboardWillHide:(NSNotification *)notification {

NSDictionary* userInfo = [notification userInfo];

/*
Restore the size of the text view (fill self's view).
Animate the resize so that it's in sync with the disappearance of the keyboard.
*/
NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration;
[animationDurationValue getValue:&animationDuration];

[self moveInputBarWithKeyboardHeight:0.0 withDuration:animationDuration];
}
复制代码

  3)在视图控制器消除时,移除键盘事件的通知:

[[NSNotificationCenter defaultCenter] removeObserver:self];


ps:

  ios5隐藏功能分享——“字典”功能(英英字典):

  在任何输入框中选中一个英文单词,此时会有选择项“复制”,“删除”...等,还有一个向右的箭头,点击这个向右的箭头后,就会出现“定义”选项,点击这个“定义”按钮即会弹出这个英语单词的英文解释。


首先,你得监听键盘的事件,最基本的两个事件:

UIKeyboardWillShowNotification

UIKeyboardWillHideNotification

UIKeyboard...

iOS 5新增加了一些

UIKeyboardDidChangeFrameNotification(will)

一般情况下,前两个事件已经可以完成你要做的事情。在你的事件处理方法中加上NSNotification参数可以为你获得更多的东西:

view plainprint?

- (void)keyboardWillShow:(NSNotification *)notification 

{  

    CGPoint beginCentre = [[[notification userInfo] valueForKey:UIKeyboardCenterBeginUserInfoKey] CGPointValue]; 

    CGPoint endCentre = [[[notification userInfo] valueForKey:UIKeyboardCenterEndUserInfoKey] CGPointValue]; 

    CGRect keyboardBounds = [[[notification userInfo] valueForKey:UIKeyboardBoundsUserInfoKey] CGRectValue]; 

    CGRect keyboardFrames = [[[notification userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 

    UIViewAnimationCurve animationCurve = [[[notification userInfo] valueForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; 

    NSTimeInterval animationDuration = [[[notification userInfo] valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 

 如果你要在程序中使用键盘的高度和宽度,永远不要尝试去手动指定,动态获取也很简单而且一定准确,不会出现键盘

挡住输入框的问题。

你可以利用这些参数把动画做的和键盘一致。假设你要把一个控件放在Window上,并且想让它的交互方式和键盘一样,

如果只是简单的做个向下偏移动画并不能很好的完成,因为你还要考虑从导航栏中Pop出来的时候,这个时候的键盘动画是

在x轴上偏移的,你用UIKeyboardFrameEndUserInfoKey获取的frame可以很准确的做到。

 

如果在某些特殊的字段上,你不想用默认的键盘,而是用类似于Picker这样的拾取器,你只需要设置inputView就行了,用你自定义的视图去替换掉键盘;如果你想在键盘上面再增加一个视图,比如toolbar,那么你可以不用自己对toolbar的位置进行控制,只需要设置inputAccessoryView就行了,这个值默认为nil,设置的视图将在你的控件变成第一响应者的时候显示在inputView的上方。

\\

 

在UIScrollView(UITableView继承于它)上,当你触碰控件使之变成第一响应者的时候,系统会自动调整位置,避免键盘挡住控件。如果在代码中用becomeFirstResponder使之变成第一响应者将不会出现自动调整。你可以设置contentOffset去手动调整。其他视图,最简单的方法就是修改控件的frame属性,让控件总是显示在可见区域。


IOS键盘事件记

IOS5.0之前不支持键盘sizechange事件(5.0之前键盘尺寸一直保持不变),而5.1居然在键盘size改变时无法正常发出通知。所以要想捕获键盘尺寸变化的事件,可以在键盘didShow事件里通过beginSize和endSize和判断。


如果想让UI随着键盘的变化而变化(动画一致),需要在willshow及willhide里加入动画代码。动画的两个参数需要和键盘同步(animationDuration和animationCurve)。

获取键盘的动画参数:

NSDictionary *info = [notification userInfo];

NSTimeInterval duration = 0;

UIViewAnimationCurve curve;

[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration];

[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve];


duration在默认【中文拼音输入法】弹出时,不能正确获取duration,需要加一行代码修正:

duration = (duration > 0 ? duration: 0.25);//已知,IOS5.0.1里面键盘弹出动画的0.25S的,瑕疵:如果这里动画时间不是0.25就有可能动画不同步了


【Updated at 2012-05-12】键盘处于显示状态的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显示

...

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

广告投放| 申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

返回顶部