iOS_22自定义键盘工具栏
最后效果图:
Main.storyboard
KeyboardTool.xib
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
KeyboardTool.h
// KeyboardTool.h
// 键盘处理
// Created by beyond on 14-8-24.
// Copyright (c) 2014年 com.beyond. All rights reserved. #import <UIKit/UIKit.h>
@protocol KeyboardToolDelegate; typedef enum {
kKeyboardToolButtonTypeNext, // 下一个button
kKeyboardToolButtonTypePrevious, // 上一个button
kKeyboardToolButtonTypeDone // 完毕button
} KeyboardToolButtonType; @interface KeyboardTool : UIToolbar // 上一个button控件
@property (nonatomic, weak) IBOutlet UIBarButtonItem *previousBtn; // 下一个button控件
@property (nonatomic, weak) IBOutlet UIBarButtonItem *nextBtn; // 完毕button控件
@property (nonatomic, weak) IBOutlet UIBarButtonItem *doneBtn; // 代理一般用weak,同一时候,避免与默认的继承的delegate冲突
@property (nonatomic, weak) id<KeyboardToolDelegate> toolDelegate; // 类方法 返回一个实例对象
+ (id)keyboardTool; // 监听工具条上 三个button的点击 事件
- (IBAction)previousBtnClicked; - (IBAction)nextBtnClicked; - (IBAction)doneBtnClicked;
@end
KeyboardTool.m
// KeyboardTool.m
// 键盘处理
// Created by beyond on 14-8-24.
// Copyright (c) 2014年 com.beyond. All rights reserved. #import "KeyboardTool.h"
#import "KeyboardToolDelegate.h" @implementation KeyboardTool // 类方法,从xib文件里初始化一个KeyboardTool
+ (id)keyboardTool {
// owner能够传KeyboardTool这个类
// 点击"下一个"button的时候。要调用owner的next方法 NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"keyboardTool" owner:nil options:nil]; // 返回初始化完毕的KeyboardTool对象
return array[0];
}
#pragma mark - 点击事件
// 点击了上一个button
- (void)previousBtnClicked {
if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) {
// 告诉代理,点击的是上一个button
[_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypePrevious];
}
}
// 点击了下一个button
- (void)nextBtnClicked {
if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) {
// 告诉代理,点击的是下一个button
[_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypeNext];
}
} // 点击了完毕button
- (void)doneBtnClicked {
if ([_toolDelegate respondsToSelector:@selector(keyboardTool:buttonType:)]) {
// 告诉代理,点击的是完毕button
[_toolDelegate keyboardTool:self buttonType:kKeyboardToolButtonTypeDone];
}
}
@end
KeyboardToolDelegate.h
//
// KeyboardToolDelegate.h
// 22_键盘综合案例
//
// Created by beyond on 14-8-24.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// #import <Foundation/Foundation.h>
@class KeyboardTool; @protocol KeyboardToolDelegate <NSObject>
- (void)keyboardTool:(KeyboardTool *)tool buttonType:(KeyboardToolButtonType)type;
@end
BeyondViewController.h
//
// BeyondViewController.h
// 22_键盘综合案例
//
// Created by beyond on 14-8-24.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// #import <UIKit/UIKit.h>
#import "KeyboardTool.h"
#import "KeyboardToolDelegate.h" @interface BeyondViewController : UIViewController <UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate, KeyboardToolDelegate>
// 生日输入框
@property (weak, nonatomic) IBOutlet UITextField *birthdayTextField;
// 城市输入框
@property (weak, nonatomic) IBOutlet UITextField *cityTextField; @end
BeyondViewController.m
//
// BeyondViewController.m
// 22_键盘综合案例
//
// Created by beyond on 14-8-24.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// #import "BeyondViewController.h" @interface BeyondViewController () // 全部省名组成的数组
@property (nonatomic, strong) NSArray *provinceNameArr;
// 字典:省名key---value城市名组成的数组
@property (nonatomic, strong) NSDictionary *provinceName_cities_Dict;
// 当前激活的活跃状态的输入框
@property (nonatomic, weak) UITextField *currentTextField;
// 键盘上的工具条
@property (nonatomic, weak) KeyboardTool *tool;
// 全部输入框控件 组成的数组
@property (nonatomic, strong) NSMutableArray *allTextFields; @end @implementation BeyondViewController - (void)viewDidLoad
{
[super viewDidLoad]; self.allTextFields = [NSMutableArray array];
// 类方法,实例化一个KeyboardTool对象
self.tool = [KeyboardTool keyboardTool];
self.tool.backgroundColor = [UIColor clearColor];
self.tool.barTintColor = [UIColor lightGrayColor]; // 而且设置键盘工具的代理为当前控制器,用于接收其内部的btn点击事件,感知btnType
self.tool.toolDelegate = self; // 1.设置全部文本框的键盘工具条 都是 自己定义的KeyboardTool
for (UITextField *field in self.view.subviews)
{
// 假设不是文本输入框,继续
if (![field isKindOfClass:[UITextField class]]) continue; // 每个文本输入框的键盘工具都是它...
field.inputAccessoryView = self.tool;
// 数组保存全部的文本输入框控件,后面要用到
[self.allTextFields addObject:field];
// 设置每个文本输入框的代理都是当前控制器
field.delegate = self;
} // 2.为生日输入框,设置键盘为DatePicker
[self setInputViewForBirthdayTextField]; // 3.为城市输入框,设置键盘为DatePicker
[self setInputViewForCityTextField]; // 4.载入全部的数据
[self loadAllData]; } // 2.为生日输入框,设置键盘为DatePicker
- (void)setInputViewForBirthdayTextField
{
// 设置生日的键盘(不用设置宽高和位置)
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
// 设置区域为中国中文简体
datePicker.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
// 模式为:仅仅显示日期
datePicker.datePickerMode = UIDatePickerModeDate;
// 监听datePicker的值改事件
[datePicker addTarget:self action:@selector(datePickerValueChangeed:) forControlEvents:UIControlEventValueChanged];
// 设置其为生日输入框的view
self.birthdayTextField.inputView = datePicker;
} // 3.为城市输入框,设置键盘为DatePicker
- (void)setInputViewForCityTextField
{
// 设置城市的键盘
UIPickerView *picker = [[UIPickerView alloc] init];
// 设置数据源和代理
picker.dataSource = self;
picker.delegate = self;
// 显示指示器
picker.showsSelectionIndicator = YES;
// 设置其为城市输入框的view
self.cityTextField.inputView = picker;
}
// 4.载入全部的数据
- (void)loadAllData
{
// 载入省份数据
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cities" ofType:@"plist"]];
// 全部以省名组成的数组
self.provinceNameArr = dict[@"provinces"];
// 字典,键是省名,值是城市名组成的数组
self.provinceName_cities_Dict = dict[@"cities"];
} // 2.1监听生日选择控件的值改变事件,为生日输入框赋值
- (void)datePickerValueChangeed:(UIDatePicker *)picker
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd";
// 生日输入框赋值
self.birthdayTextField.text = [formatter stringFromDate:picker.date];
} #pragma mark - PickerView数据源方法
// 一共多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
// 第一列是省名,第二列是省名相应的城市数组
return 2;
}
// 每一列相应多少行
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
// 返回省名数组的长度
return self.provinceNameArr.count;
} else {
// 返回第1列 当前选中的行号
NSUInteger rowNum = [pickerView selectedRowInComponent:0];
// 先从省名数组,取出相应的省名
NSString *pName = self.provinceNameArr[rowNum];
// 再从字典中,通过省名,获取城市数组,并返回其长度
NSArray *cityArr = self.provinceName_cities_Dict[pName];
return cityArr.count;
}
} // 每列每行显示什么数据
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
//前一列,显示省名
return self.provinceNameArr[row];
} else {
// 返回第1列 当前选中的行号
NSUInteger rowNum = [pickerView selectedRowInComponent:0];
// 先从省名数组,取出相应的省名
NSString *pName = self.provinceNameArr[rowNum];
// 再从字典中,通过省名,获取城市数组,并返回其长度
NSArray *cityArr = self.provinceName_cities_Dict[pName];
return cityArr[row];
}
}
// UIPickerView选中了某一行就会调用
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// 刷新后一列的数据,联动效果
[pickerView reloadComponent:1]; NSUInteger pRowNum = [pickerView selectedRowInComponent:0];
// 先从省名数组,取出相应的省名
NSString *pName = self.provinceNameArr[pRowNum]; NSUInteger cRowNum = [pickerView selectedRowInComponent:1];
// 再从字典中,通过省名,获取城市数组,并返回其相应的城市名
NSArray *cityArr = self.provinceName_cities_Dict[pName];
NSString *cName = cityArr[cRowNum];
// 城市输入框赋值
self.cityTextField.text = [NSString stringWithFormat:@"%@ %@", pName, cName];
} #pragma mark - 重点!!!!!!!!keyboardTool代理方法
- (void)keyboardTool:(KeyboardTool *)tool
buttonType:(KeyboardToolButtonType)type
{ if (type == kKeyboardToolButtonTypeDone) {
//当点击完毕时,当前活动的输入框,取消第一响应者,退出键盘
[self.currentTextField resignFirstResponder];
} else {
//先取出当前输入框在输入框数组中的索引,
NSUInteger index = [self.allTextFields indexOfObject:self.currentTextField];
if (type == kKeyboardToolButtonTypePrevious) {
//当点击上一个时,索引减1,
index--;
} else {
//当点击下一个时,索引加1,
index++;
}
// 取出相应索引的输入框,成为即将成为的第一响应者,调出相应的键盘
UITextField *field = self.allTextFields[index];
[field becomeFirstResponder];
}
} #pragma mark - 重点!!!!!!!UITextField代理方法
- (void)textFieldDidBeginEditing:(UITextField *)textField
{ // 记住被激活的文本框,其它方法keyboardTool:buttonClick:中要用到
self.currentTextField = textField; // 先取得本输入框在全部输入框组成的数组中的索引
NSUInteger index = [self.allTextFields indexOfObject:textField];
// 设置下一个按钮的,是否可用
self.tool.nextBtn.enabled = index != self.allTextFields.count - 1;
// 设置上一个按钮的,是否可用
self.tool.previousBtn.enabled = index != 0; }
// 这个是 UITextField的一个托付方法!
// 利用这个托付 我们在打开键盘的时候。点击return 就能够关闭键盘了
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
// 结束全部编辑,退出全部键盘,而且返回YES就能够
[self.view endEditing:YES];
return YES;
}
@end
数据源
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
版权声明:本文博主原创文章,博客,未经同意不得转载。
iOS_22自定义键盘工具栏的更多相关文章
- 【iOS自定义键盘及键盘切换】详解
[iOS自定义键盘]详解 实现效果展示: 一.实现的协议方法代码 #import <UIKit/UIKit.h> //创建自定义键盘协议 @protocol XFG_KeyBoardDel ...
- ios 自定义键盘
由于项目需要,需要自定义键盘.ios系统键盘会缓存键盘输入,并保存在系统目录下的文件里,并且是明文存储,存在帐号密码泄漏风险.在别人代码基础上修改了下,美化了下界面,去掉了字符输入,加了点击特效,截图 ...
- 自定义底部工具栏及顶部工具栏和Fragment配合使用demo
首先简单的介绍下fragment,fragment是android3.0新增的概念,其中文意思是碎片,它与activity非常相似,用来在一个activity中描述一些行为或一部分用户界面.使用锁个f ...
- UI:自定义键盘的实现
自定义我的封装键盘,并在试图控制器里对接 (解决多 输入框问题,把输入框存入到可变数组) @implementation AppDelegate - (BOOL)application:(UIAppl ...
- UI:登录窗的自定义键盘
在创建一个自定义键盘的时候遇到的错误 //双重for循环,对于Button上的数字用二维数组 // NSArray * butArr[4][3] = {@[@"1",@&qu ...
- 键盘工具栏的快速集成--HcCustomKeyboard
源项目地址:HcCustomKeyboard HcCustomKeyboard是一个键盘工具栏控件: 效果: HcCustomKeyboard使用很方便: 三部: 添加控件->操作处理-> ...
- Vue2.0的变化 ,组件模板,生命周期,循环,自定义键盘指令,过滤器
组件模板: 之前: <template> <h3>我是组件</h3><strong>我是加粗标签</strong> </templat ...
- vue.js之过滤器,自定义指令,自定义键盘信息以及监听数据变化
一.监听数据变化 1.监听数据变化有两种,深度和浅度,形式如下: vm.$watch(name,fnCb); //浅度 vm.$watch(name,fnCb,{deep:true}); //深度监视 ...
- 雷林鹏分享:jQuery EasyUI 窗口 - 自定义窗口工具栏
jQuery EasyUI 窗口 - 自定义窗口工具栏 默认情况下,窗口(window)有四个工具:collapsible.minimizable.maximizable 和 closable.比如我 ...
随机推荐
- 持久化redis
redis持久化 Redis持久化原理: Redis支持两种持久化:RDB和AOF模式 一.名词解释: RDB:持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snap ...
- PowerMockito使用详解(转)
一.为什么要使用Mock工具 在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件,网络通讯,远程服务, 文件系统等等). 而我们没法控制这些外部依赖的对象,为了解 ...
- Android供TextView添加多个点击文字
我们使用社会性软件的过程中会或多或少像别人的帖子点,图. : 能够看到用户页面显示出来的仅仅是点了赞的用户的名称,点击这些名称能够进入到该用户的主页.我们就来实现相似的效果.直接上代码吧. @Over ...
- 用python做自己主动化測试--对server端的自己主动化測试(3)-很多其它http client实例
上一篇中仅仅是实现了一个非常easy的http client功能,request还提供了keep alive, SSL, 多文件上传,cookie 管理功能,http requests头管理等丰富的功 ...
- Java IO的RandomAccessFile的使用(转)
现有如下的一个需求,向已存在1G数据的txt文本里末尾追加一行文字,内容如下“Lucene是一款非常优秀的全文检索库”.可能大多数朋友会觉得这个需求很easy,说实话,确实easy,然后XXX君开始实 ...
- JavaScript的隐式转换
原文:JavaScript的隐式转换 JavaScript的数据类型分为六种,分别为null,undefined,boolean,string,number,object.object是引用类型,其它 ...
- Facebook 网页应用图文设置教程
最近在弄一个项目,需要使用Facebook进行登陆并且获取用户Facebook相关的数据.网上查找有关Facebook应用设置教程,中文资料中,要么介绍的是N版之前的API,要么是App端的教程.Fa ...
- UVA 11174 Stand in a Line 树dp+算
主题链接:点击打开链接 题意:白书的P103. 加个虚根就能够了...然后就是一个多重集排列. import java.io.PrintWriter; import java.util.ArrayLi ...
- Device "/dev/sdg" is not a partition【再续】
之前创建asm磁盘的时候总结过一下错误:http://blog.csdn.net/rhys_oracle/article/details/17029333 当今天情况是这种.例如以下: 在使用open ...
- 用脚本安装IIS
原文:用脚本安装IIS 基本命令:Sysocmgr.exe /i:sysoc.inf /u:c:/iis.txt c:/iis.txt是IIS要安装的组件列表 [Components]iis_comm ...