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.比如我 ...
随机推荐
- c#获取页面重定向url
/// <summary> /// 获取页面重定向url /// </summary> /// <param name="url"></p ...
- 推断序列的端部的大小C规划
概念 big-endian格式:高字节字符数据被存储在低地址.字数据的低字节存放在高地址. 小尾数格式:相较于大端存储格式,在小尾数格式.低地址存储在字数据的低字节.的是字数据的高字节. 如5A6C中 ...
- H.265/HEVC Codec 编解码 (MP4 和 TS)
1. H.265/HEVC 播放器 1) VLC media player 2.1.3 (眼下不支持H.265 TS播放) 2)ffmpeg中的ffplay (如:ffplay hevc.ts) 3 ...
- Visual Studio 2015使用EF6的ModelFirst模式添加实体数据模型缺少tt文件问题
在看实体框架 (EF) 入门的时候,当按照样例做到ModelFirst的时候出问题了 这是使用vs2015新建的实体数据模型 这是官网样例 对比样例截图,会发现里面缺少.tt的文件.最重要的是最终代码 ...
- 渲染优化 之fixed与返回顶部 以及开启GPU Hack
fixed元素,常见网站右侧出现一个返回顶部的按钮,滚动的时候,会发现返回顶部这个区域在不停的进行重绘,而返回顶部是position:fixed定位的.这也解释了为什么fixed定位是最耗性能的属性之 ...
- Mozilla5.0的含义
mod=viewthread&tid=757008">http://www.lightnovel.cn/forum.php?mod=viewthread&tid=757 ...
- eclipse 在win7 64两个图标出现位操作系统无法锁定到任务栏或任务栏
eclipse 在win7 64位操作系统无法锁定到任务栏或者任务栏上出现两个图标 解决的方法 eclipse在win7 64bit下无法锁定到任务栏问题(或是锁定后任务栏出现两个eclipse图标) ...
- vs2010中文简体版下载链接(含中文msdn)
昨天朋友说vs2010中文版能够下载了,自己開始还不相信,正好周末,于是就下载了试一下 安装了果然是中文版,本来是msdn订阅用户才干够下载的,感谢上传的网友. 文件名称 cn_visual_stud ...
- Linux下is not in the sudoers file(转)
用sudo时提示"xxx is not in the sudoers file. This incident will be reported.其中XXX是你的用户名,也就是你的用户名没有权 ...
- 介绍 Microservice
介绍 Microservice 这篇文章转自我的 Github blog 一天我司招财猫姐(HR 大人)问我,你给我解释一下 Microservice 是什么吧.故成此文.一切都是从一个创业公司开始的 ...