为什么要做这个效果

在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会跟随键盘一起向下收回,二者完全无缝连接,那么这是怎么实现的呢,也许你会说直接在键盘弹出的时候把输入框也向上移动不就行了?但是我使用这种方法的时候,发现效果十分不理想,会有明显的滞后现象,原因有以下几点:

1.键盘弹出动画并不是匀速,键盘和输入框的时间曲线不完全一致,运动不同步 
2.各种键盘的高度不一样(比如搜狗输入法就比系统自带键盘要高) 
3.无法确定键盘动画的时间,会导致延迟

解决方案

使用本地通知,对键盘的状态(弹出、收回)进行监控,当键盘状态发生改变时,在相应的方法中对输入框的位置进行操作。

这里应用了两种在ios编程中很重要的思想:Key-value coding (KVC)key-value observing (KVO)

1.使用NSNotificationCenter.defaultCenter().addObserver()添加对UIKeyboardWillShowNotificationUIKeyboardWillHideNotification键的监控,当这些值发生改变时发送通知

NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyBoardWillShow:", name:UIKeyboardWillShowNotification, object: nil)NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyBoardWillHide:", name:UIKeyboardWillHideNotification, object: nil)

2.实现两个监控方法

实现键盘弹出的方法:

func keyBoardWillShow(note:NSNotification)
{//1let userInfo  = note.userInfo as! NSDictionary//2var  keyBoardBounds = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue//3var keyBoardBoundsRect = self.view.convertRect(keyBoardBounds, toView:nil)//4var keyBaoardViewFrame = keyBaordView.framevar deltaY = keyBoardBounds.size.height//5let animations:(() -> Void) = {self.keyBaordView.transform = CGAffineTransformMakeTranslation(0,-deltaY)if duration > 0 {let options = UIViewAnimationOptions(UInt((userInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))UIView.animateWithDuration(duration, delay: 0, options:options, animations: animations, completion: nil)}else{animations()}}

代码分析

//1

let userInfo  = note.userInfo as! NSDictionary

将通知的用户信息取出,转化为字典类型,里面所存的就是我们所需的信息:键盘动画的时长、时间曲线;键盘的位置、高度信息。有了这些信息我们就可以do some magic了~

//2 通过对应的键UIKeyboardFrameEndUserInfoKey,取出键盘位置信息 通过UIKeyboardAnimationDurationUserInfoKey,取出动画时长信息 //3

var keyBoardBoundsRect = self.view.convertRect(keyBoardBounds, toView:nil)

由于取出的位置信息是绝对的,所以要将其转换为对应于当前view的位置,否则位置信息会出错!

 var keyBaoardViewFrame = keyBaordView.framevar deltaY = keyBoardBounds.size.height

保存下输入框的位置信息和y坐标需要变换的量以便后面调用

//5

   let animations:(() -> Void) = {self.keyBaordView.transform = CGAffineTransformMakeTranslation(0,-deltaY)if duration > 0 {let options = UIViewAnimationOptions(UInt((userInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))UIView.animateWithDuration(duration, delay: 0, options:options, animations: animations, completion: nil)}else{animations()}}

首先使用仿射变换CGAffineTransformMakeTranslation,使输入框的高度减少deltaY也就是跟随键盘的位置向上移动;

此处难点在这里

let options = UIViewAnimationOptions(UInt((userInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))

这里是将时间曲线信息(一个64为的无符号整型)转换为UIViewAnimationOptions类型,要通过左移16来完成类型转换。

这个方法是在一个比较著名的解决bug的网站stackoverflow里找到的。

自我感觉这是比较坑的地方,它居然没有用来进行类型转换的方法,竟然还得要位!运!算!不过相信今后这个坑会被apple填上吧。。

然后呢就是把这些东西全部装进UIView的动画函数中,执行动画。

 UIView.animateWithDuration(duration, delay: 0, options:options, animations: animations, completion: nil)

这样键盘弹出的方法就完全实现了!

接下来就是收回键盘的部分了:

这部分呢就比较简单了,收回键盘时只需要动画时长duration和时间曲线信息options所以只要留下他们就行了,然后再将输入框的位置还原即可,这里有一个很巧妙的办法

self.keyBaordView.transform = CGAffineTransformIdentity

这样就可以还原所有变换~ 下面是该方法的实现:

func keyBoardWillHide(note:NSNotification)
{let userInfo  = note.userInfo as! NSDictionarylet duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValuelet animations:(() -> Void) = {self.keyBaordView.transform = CGAffineTransformIdentity}if duration > 0 {let options = UIViewAnimationOptions(UInt((userInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))UIView.animateWithDuration(duration, delay: 0, options:options, animations: animations, completion: nil)}else{animations()}}

实际上这个方法不会运行,因为并没有判断是否应该收回键盘,我的解决方法是当手指点击输入框之上的任何地方就会收回键盘,这个在我的完整demo会看到。

demo源码github

swift实现ios类似微信输入框跟随键盘弹出的效果相关推荐

  1. 【土旦】vue 解决ios H5底部输入框 获取焦点时弹出虚拟键盘挡住输入框 以及监听键盘收起事件...

    问题描述 im聊天H5页面,在iOS系统下,inpu获取焦点弹出系统虚拟键盘时,会出现挡住input的情况,十分影响用户体验. bug图 解决方法: html: <input type=&quo ...

  2. iOS 仿微信首页下拉弹出小程序

    下载demo链接地址:https://github.com/825197989/iOS-.git

  3. Android11键盘弹出动画,(2016-11-04完美解决)移动端iOS第三方输入法遮挡底部input及android键盘回落后留白问题...

    问题概述 问题1:H5 web 移动端 输入框, 键盘唤起后fixed定位好的元素跟随页面滚动了起来- fixed属性失效了!满屏任性横飞, 如下图: 问题2:有几后来含些在到气时按式近篇来又的方浏消 ...

  4. 解决Android软键盘弹出覆盖h5页面输入框问题 // 在ios系统中输入框软键盘消失后,页面不回弹的问题 // 解决苹果不回弹页面 // 微信环境打开

    //解决Android软键盘弹出覆盖h5页面输入框问题 window.addEventListener('resize', () => {if (document.activeElement.t ...

  5. ios输入框的坑(软键盘弹出不灵敏、输入法影响弹出高度)

    参考地址: https://segmentfault.com/a/1190000018959389 https://blog.csdn.net/github_37533433/article/deta ...

  6. ios 键盘弹出input输入框被遮挡 键盘隐藏时页面无法回弹解决方案

    ios 微信键盘弹出input输入框被遮挡 键盘隐藏时页面无法回弹解决方案 问题:测试发现ios微信端浏览器中,键盘弹出后,输入框被软键盘遮挡,input失焦后,因软键盘顶起的页面没有回弹到原来位置, ...

  7. 成品app直播源码,iOS键盘弹出遮挡输入框

    成品app直播源码,iOS键盘弹出遮挡输入框解决的相关代码 self.phoneInput = [UITextField new];self.phoneInput.placeholder = @&qu ...

  8. html5手机底部输入框,html5 虚拟键盘弹出挡住底部的输入框解决方案

    问题描述: 我们使用 h5 做移动网站开发时,如果文本框在页面的下方,当输入信息弹出的软键盘会将输入框挡住(Android 会有这个问题,IOS会自动将整个页面上移),IOS中软键盘关闭后,页面上移的 ...

  9. 仿微信软键盘弹出与隐藏

    仿微信软键盘弹出与隐藏,效果图如下: 实现输入框弹出,软键盘弹出,获取焦点,否则失去焦点. 首先在 AndroidManifest 文件的对应 Activity 中加入下面代码: android:wi ...

最新文章

  1. python模块之hashlib加密
  2. SQL求一个表中非重复数据及其出现的次数
  3. Modular multiplicative inverse 模逆元
  4. python最小二乘法求a b_python_numpy实用的最小二乘法理解
  5. SharePoint REST API - 一个请求批量操作
  6. Linux学习总结(76)—— Shell 脚本日志技巧
  7. mysql配置文件没有权限更改_MySQL配置文件无法修改的解决方法(Win10)
  8. 【TensorFlow系列】【九】利用tf.py_func自定义算子
  9. 江苏省计算机等级考试注意事项,江苏省淮安市2020上半年计算机等级考试注意事项...
  10. 逻辑门图解(NOT门 AND门 OR门 XOR门)
  11. 厦门大学计算机专业录取分数线2019,厦门大学2019年各省录取分数线及各专业录取分数线...
  12. 本地idea通过tomcat启动服务停滞
  13. Excel: vlookup函数简介、使用注意事项及查找结果显示#N/A的解决方法
  14. Google 最大数据中心发生爆炸,三名技术人员受伤
  15. AForge学习笔记(10):AForge.Imaging.Filters
  16. 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 待补
  17. 计算机专业不会打字怎么办,科目一考试电脑怎么用?科目一不会打字怎么办
  18. Python代码实现PID控制
  19. 4G拨号上网 之 AT指令学习
  20. 环保设施用电监管云平台、蓝天碧水保卫战解决方案

热门文章

  1. FFmpeg中一个线程获取视频流一个线程执行scale测试代码
  2. 【linux】Matchbox(一):启动脚本
  3. java 序列化 缓存_java_缓冲流、转换流、序列化流
  4. python中str的index什么意思_python中index的用法是什么
  5. SQL基础学习总结:2(表的创建、删除、更新和名称修改)
  6. Java项目:平行志愿管理系统(java+Springboot+Maven+mybatis+Vue+Mysql)
  7. python 更新pip 失败问题总结
  8. Android Studio开发环境及第一个项目
  9. idea springmvc_SSM三大框架使用Maven快速搭建整合(SpringMVC+Spring+Mybatis)
  10. iOS 关于UIView覆盖StatusBar的小知识点