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)
{
//1
let userInfo = note.userInfo as! NSDictionary
//2
var keyBoardBounds = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
//3
var keyBoardBoundsRect = self.view.convertRect(keyBoardBounds, toView:nil)
//4
var keyBaoardViewFrame = keyBaordView.frame
var deltaY = keyBoardBounds.size.height
//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()
}
}
代码分析
//1
let userInfo = note.userInfo as! NSDictionary
将通知的用户信息取出,转化为字典类型,里面所存的就是我们所需的信息:键盘动画的时长、时间曲线;键盘的位置、高度信息。有了这些信息我们就可以do some magic了~
//2
通过对应的键UIKeyboardFrameEndUserInfoKey
,取出键盘位置信息
通过UIKeyboardAnimationDurationUserInfoKey
,取出动画时长信息
//3
var keyBoardBoundsRect = self.view.convertRect(keyBoardBounds, toView:nil)
由于取出的位置信息是绝对的,所以要将其转换为对应于当前view的位置,否则位置信息会出错!
//4
var keyBaoardViewFrame = keyBaordView.frame
var 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! NSDictionary
let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
let 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的效果:

原文链接:http://www.jianshu.com/p/4e755fe09df7
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
swift实现ios类似微信输入框跟随键盘弹出的效果的更多相关文章
- 【转】swift实现ios类似微信输入框跟随键盘弹出的效果
swift实现ios类似微信输入框跟随键盘弹出的效果 为什么要做这个效果 在聊天app,例如微信中,你会注意到一个效果,就是在你点击输入框时输入框会跟随键盘一起向上弹出,当你点击其他地方时,输入框又会 ...
- 【土旦】vue 解决ios H5底部输入框 获取焦点时弹出虚拟键盘挡住输入框 以及监听键盘收起事件
问题描述 im聊天H5页面,在iOS系统下,inpu获取焦点弹出系统虚拟键盘时,会出现挡住input的情况,十分影响用户体验. bug图 解决方法: html: <input type=&quo ...
- 微信浏览器软键盘弹出与页面resize的问题
使用微信打开网页,弹出软键盘时遇到的兼容问题 过去开发中遇到过很多这种情况,页面底部需要固定定位一个按钮,广告栏或者菜单栏,页面中有表单项需要填写,在打开手机虚拟键盘的时候,底部固定定位的元素会处在软 ...
- Android封装类似微信的顶部TitleBar弹出的PopupWindow代码
Android仿微信顶部titlebar,点击加号弹出的PopupWindow,是封装好的PopupWindow,直接拿来用即可,先看效果图: 调用代码非常简单,这是MainActivity的代码: ...
- ToolBar跟随键盘弹出和隐藏
实现效果如下: 代码实现如下: // // ViewController.m // PopToolBarDemo // // Created by 思 彭 on 2017/7/20. // Copyr ...
- iOS 键盘弹出遮挡输入框
#pragma mark 键盘弹出遮挡输入框 //开始编辑输入框的时候,软键盘出现,执行此事件 -(void)textFieldDidBeginEditing:(UITextField *)textF ...
- iOS学习——键盘弹出遮挡输入框问题解决方案
在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发 ...
- iOS学习——tableview中带编辑功能的cell键盘弹出遮挡和收起问题解决
最近在项目中经常用到UITableView中的cell中带有UITextField或UITextView的情况,然后在这种场景下,当我们点击屏幕较下方的cell进行编辑时,这时候键盘弹出来会出现遮挡待 ...
- Android软键盘弹出,覆盖h5页面输入框问题
之前我们在使用vue进行 h5 表单录入的过程中,遇到了Android软键盘弹出,覆盖 h5页面 输入框 问题,在此进行回顾并分享给大家: 系统:Android 条件:当输入框在可视区底部或者偏下的位 ...
随机推荐
- [转帖]gesture recognition
http://wenku.baidu.com/view/53c3331a6bd97f192279e9c9.html HSI与RGB的Matlab实现. http://wenku.baidu.com/v ...
- 爬虫爬oj用户头像
import requests import Queue import urllib import urllib2 import re import requests alreadyImg = set ...
- oracle通过query导出指定条件的数据
通过下面的方式oracle可以导出指定了条件的数据: exp mixcoaldb/mixcoaldb@server tables=(shengcssjk) query=\"where to_ ...
- Win7下启用IIS7
1.进入“控制面板-->程序”: 2.点击“打开或关闭Windows功能” 3.选择“Internet信息服务”相关选项,如下: 点击“确定”后,请稍等.. 5.启用成功后,可在浏览器访问:ht ...
- 简化的nginx多进程模型demo
//version 1:以下代码仅演示nginx多进程模型[test@vm c]$ cat mynginx.c#include <stdio.h> #include <string. ...
- Unity扩展编辑器--类型1:Editor Windows
Extending the Editor Unity允许你使用自己定制的inspectors和Editor Windows扩展编辑器,并且你可以使用定制的Property Drawers定义属性集在i ...
- CodeKata
http://codekata.pragprog.com/2007/01/code_kata_backg.html#more 背景 你如何成为一个伟大的音乐家?它有助于知道理论,了解仪器的机制.它有助 ...
- asp.net framework identity 学习笔记
关于 cookie expiry & securityStamp http://www.jamessturtevant.com/posts/ASPNET-Identity-Cookie-Aut ...
- Centos6.5 qt 安装
1,centos linux系统必须预先以安装x Server(KDE or GNOME) 2,wget http://download.qt-project.org/official_release ...
- Hadoop Compression
文件压缩主要有两方面的好处:一方面节省文件存储空间:另一方面加速网络数据传输或磁盘读写.当处理大规模的数据时这些效果提升更加明显,因此我们需要仔细斟酌压缩在Hadoop环境下的使用. 目前已经存在 ...