iOS实现输入框跟随键盘自动上移的实例代码

2020-01-18 22:27:34于海丽

看上去这样已经完美实现了输入框随键盘自动上移,我们也可以喝杯茶稍微休息一下了。没错,在iOS 8及之后的系统中,确实可以正常的工作,然而如果你的应用需要适配iOS 7并且要支持横屏,那么上面的方式在iOS7上,并不能按照我们的期望正确移动。

原因:在ios7上,键盘的frame,系统是按照竖屏状态下window坐标系来计算的,并不考虑旋转的因素,因此在横屏下得到的键盘frame是错误的。受此影响的还有横屏时获取屏幕宽高[UIScreen mainScreen].bounds,也会有这样的问题。这种情况我们不仅无法正确得到键盘的frame,而且输入框相对于window的坐标计算结果也是错误的。

因此在ios7上,键盘上端的Y坐标以及输入框下端相对于window的Y坐标需要单独处理。键盘上端的Y坐标可以通过屏幕高度减键盘高度得到。我们通过下面的方法获取键盘上端的Y坐标。


- (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;
}

输入框下端相对于window的坐标如何计算呢?我们首先获得的其实是基于竖屏状态下坐标系中的Y值,而我们期望的是横屏下得到横屏状态下坐标系中的Y值,根据两个坐标系的关系,可以将第一次转换得到的坐标再做一次转换,计算得出横屏坐标系下的Y坐标值。我们通过下面的方法获取输入框下端的Y坐标。


- (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;
}