封装一个键盘控制器(带有工具条)作为基类

2015-07-21 00:20:47 +08:00
 tunnyios
http://tunnyios.github.io/personal/keyboard/
##键盘工具条的使用

开发中经常会跟键盘打交道,键盘上添加工具条,可以方便的应对一些多textField的界面操作。如果一个项目中多处用到类似的含有工具条的键盘处理,可以使用封装的思想,实现一个基类。需要用到的地方直接继承这个基类即可。

下面说说实现的方法,以及遇到的问题:
<!--more-->

###xib自定义inputAccessoryView

这里不需要多说什么,主要是实现"上一个" "下一个" "完成"这三个功能,通过代理的方式交给baseKeyboardViewController来实现。

###baseKeyboardViewController的实现

1. 使用数组存储textField容器视图中所有的textField
2. 实现代理方法,获取当前响应的textfield的在textFieldArray中的索引来更改第一响应者
3. 使用通知来监听键盘Frame的改变,调整self.view视图的位置

###核心代码

{% highlight objective-c %}

/** 键盘事件处理 */
- (void)keyboradChangedFrame:(NSNotification *)nofi
{

//当键盘即将改变frame的时候,调整view的frame
//1. 获取当前的键盘的第一响应者index
NSInteger textIndex = [self getCurrentTextIndex];
//2. 取当前第一响应者的最大Y值
//转换坐标系到self.view
CGRect textFrame = [self.textFieldArray[textIndex] convertRect:[self.textFieldArray[textIndex] bounds] toView:self.view];
CGFloat textY = CGRectGetMaxY(textFrame);
//3. 获取当前键盘所占的view的高度
CGRect keyboradFrame = [nofi.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboradSizeY = self.view.bounds.size.height - keyboradFrame.origin.y;
//4. 两个高度相加与控制器的高度进行比较
CGFloat changeFrame = self.view.bounds.size.height - (textY + keyboradSizeY);
if (changeFrame < 0) {
//调整view位置
[UIView animateWithDuration:0.3 animations:^{
self.view.transform = CGAffineTransformMakeTranslation(0, changeFrame);
}];
}
DLog(@"%@", nofi);
}

/** 键盘的代理方法 */
- (void)keyboardTool:(HCKeyboardTool *)keyboardTool didClickItemType:(KeyboardItemType)itemType
{

//1. 获取当前响应的textfield的在textFieldArray中的索引
NSInteger textIndex = [self getCurrentTextIndex];

if (KeyboardItemTypePrevious == itemType) {
//上一步
[self previousClickWithIndex:textIndex];
} else if (KeyboardItemTypeNext == itemType) {
//下一步
[self nextClickWithIndex:textIndex];
} else {
//完成
[self doneClickWithIndex:textIndex];
}
}

/** 下一步 */
- (void)nextClickWithIndex:(NSInteger)textIndex
{
if (textIndex < (self.textFieldArray.count - 1)) {
//更改第一响应者
/* 先取消第一响应者,可以让键盘的位置改变一次,这样就可以触发一次键盘 frame改变事件 */
[self.textFieldArray[textIndex] resignFirstResponder];
[self.textFieldArray[textIndex + 1] becomeFirstResponder];
}
}

/** 完成 */
- (void)doneClickWithIndex:(NSInteger)textIndex
{
//退出键盘
[self.view endEditing:YES];
//view的frame回到初值****
[UIView animateWithDuration:0.3 animations:^{
self.view.transform = CGAffineTransformIdentity;
}];
}

{% endhighlight %}

###注意的问题

1. 如果在程序中多个控制器分别继承了该基类,一定要注意:移除通知的时机,如果控制器没有被销毁,则需要手动在子类控制器中手动移除通知。否则通知中的处理会混乱。
2. 要注意textfield的顺序,是跟添加到其父视图中顺序是一致的。

###效果图演示

![](http://7xke07.com1.z0.glb.clouddn.com/image/keyboard_ok.gif)

###demo代码分享

链接: http://pan.baidu.com/s/1jGznMbO 密码: 347m
1919 次点击
所在节点    iOS
1 条回复
dcty
2015-07-21 08:36:06 +08:00
https://github.com/hackiftekhar/IQKeyboardManager
https://github.com/michaeltyson/TPKeyboardAvoiding
这两个用起来都很无痛,没有什么需要注意的地方。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/207102

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX