封装键盘工具条为基类

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

键盘工具条的使用

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

下面说说实现的方法,以及遇到的问题:

xib自定义inputAccessoryView

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

baseKeyboardViewController的实现

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

核心代码

/** 键盘事件处理 */
- (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;
    }];
}

注意的问题

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

效果图演示

demo代码分享

链接: http://pan.baidu.com/s/1jGznMbO 密码: 347m



版权声明:自由转载-非商用-非衍生-保持署名 tunnyios 本文永久链接: http://tunnyios.github.io/personal/keyboard