最近做一个demo,有一个需求:需要在点击UIViewController输入框的键盘上添加一个Bar,Bar上有三个按钮,按钮功能分别为:跳转到上个输入框、跳转到下个输入框、隐藏键盘。 我稍微想了实现过程中的思路;
1、要有个独立的单例Manager来实现全局的管理,通过注册键盘和输入框的Notification来实现对键盘的监控;
2、键盘上的ToolBar要有开关可以显示或者不显示,用inputAccessoryView就可以实现;上面的按钮通过UIBarButtonItem来实现;
3、通过遍历当前的controller.view来找出所有的输入框,去除掉textField.hidden==true、textField.enable==false、textView.hidden==true、textView.editable==false的输入框;
4、通过当前第一响应者的位置来控制ToolBar按钮的可用不可用;
5、通过改变controller.view的坐标来实现输入框的移动,实现适配。(因为暂时没用到scrollView,没有考虑这个复杂的情况,以后有时间再加上)
做的过程中遇到一个很奇葩的问题,在UITextField的键盘弹出过程中,它的执行顺序分别是:
UITextFieldDidBeginEditing —> UIKeyboardWillShow
而对于UITextView,它的执行顺序是:
UIKeyboardWillShow —> UITextFieldDidBeginEditing
所以对两种输入框的处理不太一样,对于UITextField比较简单:在UITextFieldDidBeginEditing时设置inputAccessoryView,UIKeyboardWillShow时来改变controller.view坐标就可以。但是对于UITextView则不同:在UIKeyboardWillShow时因为获取不到UITextView所以无法设置inputAccessoryView,必须要在UITextFieldDidBeginEditing里面先resignFirstResponder再becomeFirstResponder,这样才可以完成正常的显示。
import Foundation
import UIKit
let _SingLetonAutoKeyboardManager = AutoKeyboardManager()
let kScreenWidth:CGFloat = UIScreen.mainScreen().bounds.size.width
let kScreenHeight:CGFloat = UIScreen.mainScreen().bounds.size.height
class AutoKeyboardManager: NSObject{
//是否启用键盘管理器
var enable: Bool {
willSet {
setKeyboardManagerEnable(newValue)
}
}
//启用键盘的Toolbar
var enableToolbar: Bool
//弹出动画时间
private var animationDuration: NSTimeInterval
//当前点击的控件
private var textView: UIView!
//textfiled处于的controller.view、它的上移距离、Responder数组
private var containerViewBeginFrame: CGRect
private var containerViewOffset: CGFloat
private var containerViewResponderArray: [UIView]
//键盘有没有弹出
private var keyBoardDidShow: Bool
//键盘尺寸
private var keyBoardSize: CGSize!
//键盘和输入框之间的距离
var spaceBetweenKeyboardAndTextView: CGFloat
//窗口
private var keyWindow:UIWindow? {
get {
return UIApplication.sharedApplication().keyWindow
}
}
//需要注册的消息通知
private let