服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS实现输入框跟随键盘自动上移的实例代码

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

2021-03-13 16:39凝望向北 IOS

本篇文章主要介绍了iOS实现输入框跟随键盘自动上移的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

场景还原

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

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

实现思路

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

具体方案

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

?
1
2
[[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属性就可以实现了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- (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坐标。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (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坐标。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- (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坐标的代码改用下面的方式:

?
1
2
3
4
5
//获取键盘上端y坐标
cgfloat keyboardy = [self getkeyboardy:notification.userinfo];
//获取输入框下端相对于window的y坐标
cgpoint tmp = [self getvieworiginpointtowindow:focusview];
cgfloat inputboxy = tmp.y + focusview.frame.size.height;

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

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

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

原文链接:http://www.jianshu.com/p/011932f9e1a7#

延伸 · 阅读

精彩推荐
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25