全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

场景还原

有些时候在包含输入框的页面中,点击输入框输入会因键盘弹起而遮挡住一部分输入框,影响用户体验。iOS在默认情况下并不会处理这种问题,不过我们可以自己实现键盘弹起输入框自动上移的效果。


实现思路

观察键盘的弹起与收回,当弹起的键盘会遮挡住输入框时,将输入框跟随键盘一并上移合适的距离,当键盘收回时,输入框回到原始状态。

具体方案

1. 注册两个观察者,观察键盘的弹起与收回

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

2. 在上面的keyboardWillShow和keyboardWillHide方法中分别实现输入框的上移和还原

上移

当弹起的键盘遮住了页面上的输入框时,我们应该将输入框移至键盘之上,而键盘没有遮到输入框时,并不需要操作。因此在ios的坐标系下,我们可以分别获取键盘弹起后上端的Y坐标和输入框下端的Y坐标,通过做差可以判断出键盘是否遮住了输入框。上移我们可以采用view的transform属性进行平移变换,而不是直接去操作view的frame,这样做的好处是当我们要还原view的状态时可以直接将transform重置为0,而不需要再关心计算下移时的距离。

还原(下移至原始状态)

根据前面所说,我们只要在恰当的时机操作view的transform属性就可以实现了。

- (void)keyboardWillShow:(NSNotification *)notification
{
  //获取处于焦点中的view
  NSArray *textFields = @[phoneNemberText, verifyCodeText];
  UIView *focusView = nil;
  for (UITextField *view in textFields) {
    if ([view isFirstResponder]) {
      focusView = view;
      break;
    }
  }
  if (focusView) {
    //获取键盘弹出的时间
    double duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    //获取键盘上端Y坐标
    CGFloat keyboardY = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
    //获取输入框下端相对于window的Y坐标
    CGRect rect = [focusView convertRect:focusView.bounds toView:[[[UIApplication sharedApplication] delegate] window]];
    CGPoint tmp = rect.origin;
    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) {
        self.view.transform = CGAffineTransformMakeTranslation(0, ty);
      }
    }];
  }
}

- (void)keyboardWillHide:(NSNotification *)notification
{
  //获取键盘弹出的时间
  double duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  //还原
  [UIView animateWithDuration:duration animations:^{
    self.view.transform = CGAffineTransformMakeTranslation(0, 0);
  }];
}

看上去这样已经完美实现了输入框随键盘自动上移,我们也可以喝杯茶稍微休息一下了。没错,在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;
}

因此我们将之前获取两个Y坐标的代码改用下面的方式:

//获取键盘上端Y坐标
CGFloat keyboardY = [self getKeyboardY:notification.userInfo];
//获取输入框下端相对于window的Y坐标
CGPoint tmp = [self getViewOriginPointToWindow:focusView];
CGFloat inputBoxY = tmp.y + focusView.frame.size.height;

这样就完美实现了输入框随键盘自动上移的效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# ios  # 输入框跟随键盘  # 输入框随键盘移动  # ios键盘上添加输入框  # h5 ios输入框和键盘的兼容性优化指南  # iOS项目开发键盘弹出遮挡输入框问题解决方案  # IOS 键盘挡住输入框的问题解决办法  # ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)  # iOS键盘弹出遮挡输入框的解决方法  # 输入框  # 相对于  # 我们可以  # 实现了  # 弹出  # 状态下  # 移至  # 遮住了  # 的是  # 会有  # 可以通过  # 这样做  # 可以直接  # 这种情况  # 当我们  # 在上面  # 并不能  # 我们应该  # 休息一下  # 要再 


相关文章: 北京网站制作网页,网站升级改版需要多久?  枣阳网站制作,阳新火车站打的到仙岛湖多少钱?  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  如何选择适合PHP云建站的开源框架?  如何在Tomcat中配置并部署网站项目?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  微信推文制作网站有哪些,怎么做微信推文,急?  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  如何解决ASP生成WAP建站中文乱码问题?  建站之星代理费用多少?最新价格详情介绍  微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?  成都网站制作报价公司,成都工业用气开户费用?  企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?  手机网站制作与建设方案,手机网站如何建设?  如何快速使用云服务器搭建个人网站?  TestNG的testng.xml配置文件怎么写  如何选择服务器才能高效搭建专属网站?  javascript基本数据类型及类型检测常用方法小结  建站VPS配置与SEO优化指南:关键词排名提升策略  XML的“混合内容”是什么 怎么用DTD或XSD定义  如何快速搭建虚拟主机网站?新手必看指南  如何快速搭建响应式可视化网站?  香港服务器租用每月最低只需15元?  网站制作软件有哪些,制图软件有哪些?  如何在阿里云高效完成企业建站全流程?  建站之星如何一键生成手机站?  SQL查询语句优化的实用方法总结  教程网站设计制作软件,怎么创建自己的一个网站?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  PHP 500报错的快速解决方法  代刷网站制作软件,别人代刷火车票靠谱吗?  广东专业制作网站有哪些,广东省能源集团有限公司官网?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  C#如何在一个XML文件中查找并替换文本内容  相册网站制作软件,图片上的网址怎么复制?  寿县云建站:智能SEO优化与多行业模板快速上线指南  代购小票制作网站有哪些,购物小票的简要说明?  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  魔方云NAT建站如何实现端口转发?  seo网站制作优化,网站SEO优化步骤有哪些?  家庭建站与云服务器建站,如何选择更优?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?  定制建站流程解析:需求评估与SEO优化功能开发指南  如何在阿里云域名上完成建站全流程?  子杰智能建站系统|零代码开发与AI生成SEO优化指南  如何选择最佳自助建站系统?快速指南解析优劣  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  北京网站制作公司哪家好一点,北京租房网站有哪些? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。