swift实现ios类似微信输入框跟随键盘弹出的效果
为什么要做这个效果
在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会跟随键盘一起向下收回,二者完全无缝连接,那么这是怎么实现的呢,也许你会说直接在键盘弹出的时候把输入框也向上移动不就行了?但是我使用这种方法的时候,发现效果十分不理想,会有明显的滞后现象,原因有以下几点:
1.键盘弹出动画并不是匀速,键盘和输入框的时间曲线不完全一致,运动不同步
2.各种键盘的高度不一样(比如搜狗输入法就比系统自带键盘要高)
3.无法确定键盘动画的时间,会导致延迟
解决方案
使用本地通知,对键盘的状态(弹出、收回)进行监控,当键盘状态发生改变时,在相应的方法中对输入框的位置进行操作。
这里应用了两种在ios编程中很重要的思想:Key-value coding (KVC)
和key-value observing (KVO)
1.使用NSNotificationCenter.defaultCenter().addObserver()
添加对UIKeyboardWillShowNotification
和UIKeyboardWillHideNotification
键的监控,当这些值发生改变时发送通知
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类似微信输入框跟随键盘弹出的效果相关推荐
- 【土旦】vue 解决ios H5底部输入框 获取焦点时弹出虚拟键盘挡住输入框 以及监听键盘收起事件...
问题描述 im聊天H5页面,在iOS系统下,inpu获取焦点弹出系统虚拟键盘时,会出现挡住input的情况,十分影响用户体验. bug图 解决方法: html: <input type=&quo ...
- iOS 仿微信首页下拉弹出小程序
下载demo链接地址:https://github.com/825197989/iOS-.git
- Android11键盘弹出动画,(2016-11-04完美解决)移动端iOS第三方输入法遮挡底部input及android键盘回落后留白问题...
问题概述 问题1:H5 web 移动端 输入框, 键盘唤起后fixed定位好的元素跟随页面滚动了起来- fixed属性失效了!满屏任性横飞, 如下图: 问题2:有几后来含些在到气时按式近篇来又的方浏消 ...
- 解决Android软键盘弹出覆盖h5页面输入框问题 // 在ios系统中输入框软键盘消失后,页面不回弹的问题 // 解决苹果不回弹页面 // 微信环境打开
//解决Android软键盘弹出覆盖h5页面输入框问题 window.addEventListener('resize', () => {if (document.activeElement.t ...
- ios输入框的坑(软键盘弹出不灵敏、输入法影响弹出高度)
参考地址: https://segmentfault.com/a/1190000018959389 https://blog.csdn.net/github_37533433/article/deta ...
- ios 键盘弹出input输入框被遮挡 键盘隐藏时页面无法回弹解决方案
ios 微信键盘弹出input输入框被遮挡 键盘隐藏时页面无法回弹解决方案 问题:测试发现ios微信端浏览器中,键盘弹出后,输入框被软键盘遮挡,input失焦后,因软键盘顶起的页面没有回弹到原来位置, ...
- 成品app直播源码,iOS键盘弹出遮挡输入框
成品app直播源码,iOS键盘弹出遮挡输入框解决的相关代码 self.phoneInput = [UITextField new];self.phoneInput.placeholder = @&qu ...
- html5手机底部输入框,html5 虚拟键盘弹出挡住底部的输入框解决方案
问题描述: 我们使用 h5 做移动网站开发时,如果文本框在页面的下方,当输入信息弹出的软键盘会将输入框挡住(Android 会有这个问题,IOS会自动将整个页面上移),IOS中软键盘关闭后,页面上移的 ...
- 仿微信软键盘弹出与隐藏
仿微信软键盘弹出与隐藏,效果图如下: 实现输入框弹出,软键盘弹出,获取焦点,否则失去焦点. 首先在 AndroidManifest 文件的对应 Activity 中加入下面代码: android:wi ...
最新文章
- python模块之hashlib加密
- SQL求一个表中非重复数据及其出现的次数
- Modular multiplicative inverse 模逆元
- python最小二乘法求a b_python_numpy实用的最小二乘法理解
- SharePoint REST API - 一个请求批量操作
- Linux学习总结(76)—— Shell 脚本日志技巧
- mysql配置文件没有权限更改_MySQL配置文件无法修改的解决方法(Win10)
- 【TensorFlow系列】【九】利用tf.py_func自定义算子
- 江苏省计算机等级考试注意事项,江苏省淮安市2020上半年计算机等级考试注意事项...
- 逻辑门图解(NOT门 AND门 OR门 XOR门)
- 厦门大学计算机专业录取分数线2019,厦门大学2019年各省录取分数线及各专业录取分数线...
- 本地idea通过tomcat启动服务停滞
- Excel: vlookup函数简介、使用注意事项及查找结果显示#N/A的解决方法
- Google 最大数据中心发生爆炸,三名技术人员受伤
- AForge学习笔记(10):AForge.Imaging.Filters
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 待补
- 计算机专业不会打字怎么办,科目一考试电脑怎么用?科目一不会打字怎么办
- Python代码实现PID控制
- 4G拨号上网 之 AT指令学习
- 环保设施用电监管云平台、蓝天碧水保卫战解决方案
热门文章
- FFmpeg中一个线程获取视频流一个线程执行scale测试代码
- 【linux】Matchbox(一):启动脚本
- java 序列化 缓存_java_缓冲流、转换流、序列化流
- python中str的index什么意思_python中index的用法是什么
- SQL基础学习总结:2(表的创建、删除、更新和名称修改)
- Java项目:平行志愿管理系统(java+Springboot+Maven+mybatis+Vue+Mysql)
- python 更新pip 失败问题总结
- Android Studio开发环境及第一个项目
- idea springmvc_SSM三大框架使用Maven快速搭建整合(SpringMVC+Spring+Mybatis)
- iOS 关于UIView覆盖StatusBar的小知识点