- 不多说先上效果图:


刚开始上一个同学对于键盘上移的代码是这么写的:
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
int movementDistance = 50;
if (up)
{
CGPoint postion = [textField convertPoint:textField.frame.origin toView:nil];
movementDistance = 80 - (self.view.frame.size.height - postion.y - textField.frame.size.height);
if (movementDistance < 0)
{
return;
}
}
const float movementDuration = 0.3f; // tweak as needed
[UIView beginAnimations: @"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
CGRect frame = self.view.frame;
frame.origin.y = up?-movementDistance:64;
self.view.frame = frame;
[UIView commitAnimations];
}
其实也没错 但是问题出现在键盘没有挡住我的文本框的时候 也会自动上移 并且没有把代码抽成公共的代码 只要有文本框的地方都这么写 非常不好维护,于是我就自己把他抽成一个工具类去使用。至于好处 我就不说了.
实现思路
- 观察键盘的弹起与收回,当弹起的键盘会遮挡住输入框时,将输入框跟随键盘一并上移合适的距离,当键盘收回时,输入框回到原始状态。
注意的问题
-
如何动态获取键盘的高度,因为每个键盘的类型不一样的,这样会导致键盘的高度不可能是一个固定的值.参考:iOS键盘高度的获取
-
还得适配iOS7 支持横竖屏幕 .原因:在ios7上,键盘的frame,系统是按照竖屏状态下window坐标系来计算的,并不考虑旋转的因素,因此在横屏下得到的键盘frame是错误的。受此影响的还有横屏时获取屏幕宽高[UIScreen mainScreen].bounds,也会有这样的问题。这种情况我们不仅无法正确得到键盘的frame,而且输入框相对于window的坐标计算结果也是错误的
-
因此在ios7上,键盘上端的Y坐标以及输入框下端相对于window的Y坐标需要单独处理。键盘上端的Y坐标可以通过屏幕高度减键盘高度得到。我们通过下面的方法获取键盘上端的Y坐标。
.h文件
@interface TTKKeyBoardTool : NSObject
/**
* 实现输入框跟随键盘自动上移
*
* @param animationOfTextField 正在输入的文本框
* @param inView 当前view
*/
+ (void)animationOfTextField:(UITextField *)textField
inView:(UIView *)view;
@end
.m文件 注释写🉐️很清楚 我也不多bb了
+ (void)animationOfTextField:(UITextField *)textField inView:(UIView *)view{
__weak typeof(self) weakSelf = self;
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"UIKeyboardWillShowNotification" object:nil] subscribeNext:^(id x) {
UIView *focusView = nil;
if ([textField isFirstResponder]) {
focusView = textField;
}
NSDictionary *userInfo = [x userInfo];
if (focusView) {
//获取键盘弹出的时间
double duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
//获取键盘上端Y坐标
CGFloat keyboardY = [weakSelf getKeyboardY:userInfo];
//获取输入框下端相对于window的Y坐标
CGPoint tmp = [weakSelf getViewOriginPointToWindow:focusView];
CGFloat inputBoxY = tmp.y + focusView.frame.size.height;
//计算二者差值
CGFloat ty = keyboardY - inputBoxY;
NSLog(@"position keyboard: %f, inputbox: %f, ty: %f", keyboardY, inputBoxY, ty);
//差值小于0,做平移变换
[UIView animateWithDuration:duration animations:^{
if (ty < 0) {
view.transform = CGAffineTransformMakeTranslation(0, ty);
}
}];
}
}];
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"UIKeyboardWillHideNotification" object:nil] subscribeNext:^(id x) {
NSDictionary *userInfo = [x userInfo];
//获取键盘弹出的时间
double duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
//还原
[UIView animateWithDuration:duration animations:^{
view.transform = CGAffineTransformMakeTranslation(0, 0);
}];
}];
}
适配iOS7并且支持横竖屏幕 动态获取键盘的高度代码
+ (CGFloat)getKeyboardY:(NSDictionary *)userInfo
{
CGFloat screenHeight;
CGFloat keyboardY = 0;
CGFloat keyboardHeight = 0;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (( [[[UIDevice currentDevice] systemVersion] floatValue]<8) && UIInterfaceOrientationIsLandscape(orientation))
{
screenHeight = [[UIScreen mainScreen] bounds].size.width;
keyboardHeight = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.width;
keyboardY = screenHeight - keyboardHeight;
}
else if (( [[[UIDevice currentDevice] systemVersion] floatValue]<8) && UIInterfaceOrientationIsPortrait(orientation)) {
screenHeight = [[UIScreen mainScreen] bounds].size.height;
keyboardHeight = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
keyboardY = screenHeight - keyboardHeight;
}
else {
keyboardY = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
}
return keyboardY;
}
+ (CGPoint)getViewOriginPointToWindow:(UIView *)view
{
CGPoint origin;
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8) {
CGPoint focusViewPoint = [view convertPoint:CGPointZero toView:nil];
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (orientation == UIInterfaceOrientationLandscapeLeft) {
origin.y = focusViewPoint.x;
origin.x = [[[UIApplication sharedApplication] delegate] window].bounds.size.height - focusViewPoint.y;
}
else if (orientation == UIInterfaceOrientationLandscapeRight) {
origin.y = [[[UIApplication sharedApplication] delegate] window].bounds.size.width - focusViewPoint.x;
origin.x = focusViewPoint.y;
}
else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
origin.y = [[[UIApplication sharedApplication] delegate] window].bounds.size.height - focusViewPoint.y;
origin.x = [[[UIApplication sharedApplication] delegate] window].bounds.size.width - focusViewPoint.x;
}
else {
origin = focusViewPoint;
}
}
else {
CGRect rect = [view convertRect:view.bounds toView:[[[UIApplication sharedApplication] delegate] window]];
origin = rect.origin;
}
return origin;
}
如何调用:在你点击文本框的时候去掉用.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[TTKKeyBoardTool animationOfTextField:textField inView:self.view];
}
网友评论