ios中键盘处理源码
2013-06-20 14:17
176 查看
1:先分别设置各个文本框的键盘类型(inputview)-->在特定键盘中textediting中禁用输入。
2:然后递归绑定各个键盘的工具条(inputaccessview).
并且个各个控件绑定有顺序的tag
3:上一个和下一个功能:先找到第一响应者,然后利用tag进行切换第一响应者。
注意点(
1:当前tag等于最小tag,工具条的上一个禁掉--》在循环中
2:当前编辑的时候,判断tag和最小tag进行判断,是否禁用上一个--》在文本框代理中
)
//MJScrollView.m
//动画和事件综合例子-键盘处理
//
//Createdbymjon13-4-15.
//Copyright(c)2013年itcast.Allrightsreserved.
//
#import"MJScrollView.h"
#import"UIView+Add.h"
@interfaceMJScrollView(){
CGPoint_lastOffset;
}
@end
@implementationMJScrollView
#pragmamark-生命周期方法
-(id)initWithFrame:(CGRect)frame
{
self=[superinitWithFrame:frame];
if(self){
[selfinitial];
}
returnself;
}
-(id)init{
if(self=[superinit]){
[selfinitial];
}
returnself;
}
#pragmamark当MJScrollView从xib中创建完毕后会调用这个方法
-(void)awakeFromNib{
[selfinitial];
}
-(void)dealloc{
NSNotificationCenter*center=[NSNotificationCenterdefaultCenter];
//注意:记得要移除
[centerremoveObserver:self];
[superdealloc];
}
#pragmamark初始化
-(void)initial{
self.contentSize=self.bounds.size;
NSNotificationCenter*center=[NSNotificationCenterdefaultCenter];
//注册键盘显示的通知
[centeraddObserver:selfselector:@selector(keybordWillShow:)name:UIKeyboardWillShowNotificationobject:nil];
//注册键盘隐藏的通知
[centeraddObserver:selfselector:@selector(keybordWillHide:)name:UIKeyboardWillHideNotificationobject:nil];
}
#pragmamark键盘显示出来的时候调用
-(void)keybordWillShow:(NSNotification*)notification{
//NSLog(@"keybordWillShow,%@",notification);
CGRectkeyboardRect=[[notification.userInfoobjectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];
UITextField*textField=[UIViewfindFistResponder:self];
//toView用nil值,代表UIWindow
CGRectconvertRect=[textFieldconvertRect:textField.boundstoView:nil];
CGFloatdistance=keyboardRect.origin.y-(convertRect.origin.y+convertRect.size.height+10);
if(distance<0){//说明键盘挡住了文本框
[selfanimationWithUserInfo:notification.userInfoblock:^{
CGPointoffset=_lastOffset=self.contentOffset;
offset.y-=distance;
self.contentOffset=offset;
}];
}
}
#pragmamark键盘隐藏的时候调用
-(void)keybordWillHide:(NSNotification*)notification{
[selfanimationWithUserInfo:notification.userInfoblock:^{
self.contentOffset=_lastOffset;
}];
}
#pragmamark抽出一个方法来执行动画
-(void)animationWithUserInfo:(NSDictionary*)userInfo
block:(void(^)(void))block{
//取出键盘弹出的时间
CGFloatduration=[[userInfoobjectForKey:UIKeyboardAnimationDurationUserInfoKey]floatValue];
//取出键盘弹出的速率节奏
intcurve=[[userInfoobjectForKey:UIKeyboardAnimationCurveUserInfoKey]intValue];
[UIViewbeginAnimations:nilcontext:nil];
[UIViewsetAnimationDuration:duration];
[UIViewsetAnimationCurve:curve];
//调用block
block();
[UIViewcommitAnimations];
}
#pragmamark监听scrollview点击
-(void)touchesEnded:(NSSet*)toucheswithEvent:(UIEvent*)event{
//退出键盘
[selfendEditing:YES];
}
@end
@implementationUIView(Add)
#pragmamark递归找出第一响应者
+(UITextField*)findFistResponder:(UIView*)view{
for(UIView*childinview.subviews){
if([childrespondsToSelector:@selector(isFirstResponder)]
&&
[childisFirstResponder]){
return(UITextField*)child;
}
UITextField*field=[selffindFistResponder:child];
if(field){
returnfield;
}
}
returnnil;
}
@end
//
//MJViewController.m
//动画和事件综合例子-键盘处理
//
//Createdbymjon13-4-15.
//Copyright(c)2013年itcast.Allrightsreserved.
//
#import"MJViewController.h"
#import"KeyboardTool.h"
#import"UIView+Add.h"
//文本框最小的tag
#definekTextFieldMinTag10
@interfaceMJViewController(){
KeyboardTool*_tool;
//文本框的总数
int_textFieldCount;
}
@end
@implementationMJViewController
#pragmamark-生命周期方法
-(void)viewDidLoad
{
[superviewDidLoad];
//初始化生日文本框
[selfinitBirthday];
//初始化性别文本框
[selfinitSex];
//给所有的文本框绑定KeyboardTool
KeyboardTool*tool=[KeyboardToolkeyboardTool];
tool.delegate=self;
[selfinitKeyboardTool:toolview:self.view];
_tool=tool;
}
#pragmamark-KeyboardTool代理方法
-(void)keyboardTool:(KeyboardTool*)toolbuttonClick:(KeyboardToolButtonType)type{
//case里面有多行时,写个{}
//完成
if(type==kKeyboardToolButtonTypeDone){
[self.viewendEditing:YES];
}else{//下一个或者上一个
//获取当前的第一响应者
UITextField*responder=[UIViewfindFistResponder:self.view];
//取出新的响应者
inttag=responder.tag;
type==kKeyboardToolButtonTypeNext?tag++:tag--;
UITextField*newResponder=(UITextField*)[self.viewviewWithTag:tag];
//让newResponder称为第一响应者
[newResponderbecomeFirstResponder];
//判断是不是最上面的文本框了
tool.previousBtn.enabled=tag!=kTextFieldMinTag;
//判断是不是最下面的文本框了
intmaxTag=kTextFieldMinTag+_textFieldCount-1;
tool.nextBtn.enabled=tag!=maxTag;
//if(tag==kTextFieldMinTag){
//tool.previousBtn.enabled=NO;
//}else{
//tool.previousBtn.enabled=YES;
//}
}
}
#pragmamar-给所有的文本框绑定KeyboardTool
-(void)initKeyboardTool:(KeyboardTool*)toolview:(UIView*)view{
//static不能省略
//staticinti=0;
for(UITextField*childinview.subviews){
if([childisKindOfClass:[UITextFieldclass]]){
child.inputAccessoryView=tool;
//绑定tag
child.tag=kTextFieldMinTag+_textFieldCount;
//设置文本框的代理
child.delegate=self;
//设置文本框的返回键类型
child.returnKeyType=UIReturnKeyDone;
_textFieldCount++;
NSLog(@"%@-tag=%i",NSStringFromClass([viewclass]),child.tag);
}else{//搜索里面的文本框
[selfinitKeyboardTool:toolview:child];
}
}
}
#pragmamark-生日
#pragmamark初始化生日文本框
-(void)initBirthday{
//初始化一个日期选择控件(不用指定宽高)
UIDatePicker*picker=[[[UIDatePickeralloc]init]autorelease];
//设置显示中文
picker.locale=[[[NSLocalealloc]initWithLocaleIdentifier:@"zh_CN"]autorelease];
//只显示年月日
picker.datePickerMode=UIDatePickerModeDate;
//添加值改变的监听器
[pickeraddTarget:selfaction:@selector(birthdayChange:)forControlEvents:UIControlEventValueChanged];
self.birthday.inputView=picker;
//self.birthday.delegate=self;
}
#pragmamark监听日期选择控件的改变
-(void)birthdayChange:(UIDatePicker*)picker{
NSDateFormatter*formatter=[[[NSDateFormatteralloc]init]autorelease];
formatter.dateFormat=@"yyyy-MM-dd";
self.birthday.text=[formatterstringFromDate:picker.date];
}
#pragmamark-UITextField代理方法
#pragmamark返回NO代表不允许手动改变文本框的文本
-(BOOL)textField:(UITextField*)textFieldshouldChangeCharactersInRange:(NSRange)rangereplacementString:(NSString*)string{
//只有生日和性别才不允许修改文字
return!(textField==self.birthday||textField==self.sex);
}
#pragmamark文本框开始编辑(开始聚焦)
-(void)textFieldDidBeginEditing:(UITextField*)textField{
//判断是不是最上面的文本框了
_tool.previousBtn.enabled=textField.tag!=kTextFieldMinTag;
//判断是不是最下面的文本框了
intmaxTag=kTextFieldMinTag+_textFieldCount-1;
_tool.nextBtn.enabled=textField.tag!=maxTag;
}
#pragmamark点击了Return按钮
-(BOOL)textFieldShouldReturn:(UITextField*)textField{
[self.viewendEditing:YES];
returnYES;
}
#pragmamark-性别
#pragmamark初始化性别文本框
-(void)initSex{
UIPickerView*picker=[[[UIPickerViewalloc]init]autorelease];
//设置数据源
picker.dataSource=self;
//设置代理
picker.delegate=self;
//明显地显示选中了哪一行
picker.showsSelectionIndicator=YES;
self.sex.inputView=picker;
//self.sex.delegate=self;
}
#pragmamark-UIPickerView数据源方法
#pragmamark一共有多少列
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView{
return1;
}
#pragmamark第component列有多少行
-(NSInteger)pickerView:(UIPickerView*)pickerViewnumberOfRowsInComponent:(NSInteger)component{
return2;
}
#pragmamark-UIPickerView代理方法
//picker的每一行要保证结构是一样
//reusingView:(UIView*)view就是缓存池中的可循环利用的View
-(UIView*)pickerView:(UIPickerView*)pickerViewviewForRow:(NSInteger)rowforComponent:(NSInteger)componentreusingView:(UIView*)view{
staticinticonTag=10;
staticintlabelTag=20;
//如果没有可循环利用的View
if(view==nil){
view=[[[UIViewalloc]init]autorelease];
CGFloatviewHeight=50;
view.bounds=CGRectMake(0,0,100,viewHeight);
//添加ImageView
UIImageView*icon=[[[UIImageViewalloc]init]autorelease];
CGFloaticonX=5;
CGFloaticonWidth=32;
CGFloaticonHeight=32;
CGFloaticonY=(viewHeight-iconHeight)*0.5f;
icon.frame=CGRectMake(iconX,iconY,iconWidth,iconHeight);
icon.tag=iconTag;
[viewaddSubview:icon];
//添加文本
UILabel*label=[[[UILabelalloc]init]autorelease];
label.frame=CGRectMake(iconX+iconWidth+15,0,60,viewHeight);
label.backgroundColor=[UIColorclearColor];
label.tag=labelTag;
[viewaddSubview:label];
}
//设置图标
UIImageView*icon=(UIImageView*)[viewviewWithTag:iconTag];
icon.image=[UIImageimageNamed:row==0?@"male.png":@"female.png"];
//设置文字
UILabel*label=(UILabel*)[viewviewWithTag:labelTag];
label.text=row==0?@"男":@"女";
returnview;
}
#pragmamark监听选中了某一行
-(void)pickerView:(UIPickerView*)pickerViewdidSelectRow:(NSInteger)rowinComponent:(NSInteger)component{
self.sex.text=row==0?@"男":@"女";
}
@end
#import<UIKit/UIKit.h>
@protocolKeyboardToolDelegate;
typedefenum{
kKeyboardToolButtonTypeNext,//下一个按钮
kKeyboardToolButtonTypePrevious,//上一个按钮
kKeyboardToolButtonTypeDone//完成按钮
}KeyboardToolButtonType;
@interfaceKeyboardTool:UIToolbar
//按钮
@property(nonatomic,readonly)IBOutletUIBarButtonItem*nextBtn;
@property(nonatomic,readonly)IBOutletUIBarButtonItem*previousBtn;
@property(nonatomic,readonly)IBOutletUIBarButtonItem*doneBtn;
//代理一般用assign策略
@property(nonatomic,assign)id<KeyboardToolDelegate>delegate;
+(id)keyboardTool;
//这里写成-是为了能在xib中连线
-(IBAction)next;
-(IBAction)previous;
-(IBAction)done;
@end
@protocolKeyboardToolDelegate<NSObject>
-(void)keyboardTool:(KeyboardTool*)toolbuttonClick:(KeyboardToolButtonType)type;
@end
#import"KeyboardTool.h"
@implementationKeyboardTool
@synthesizedelegate=_toolDelegate;
#pragmamark从xib文件中初始化一个KeyboardTool
+(id)keyboardTool{
//owner可以传KeyboardTool这个类
//点击"下一个"按钮的时候,要调用owner的next方法
NSArray*array=[[NSBundlemainBundle]loadNibNamed:@"keyboardTool"owner:niloptions:nil];
//返回初始化完毕的KeyboardTool
return[arraylastObject];
}
#pragmamark-按钮点击
-(void)next{
if([_toolDelegaterespondsToSelector:@selector(keyboardTool:buttonClick:)]){
[_toolDelegatekeyboardTool:selfbuttonClick:kKeyboardToolButtonTypeNext];
}
}
-(void)previous{
if([_toolDelegaterespondsToSelector:@selector(keyboardTool:buttonClick:)]){
[_toolDelegatekeyboardTool:selfbuttonClick:kKeyboardToolButtonTypePrevious];
}
}
-(void)done{
if([_toolDelegaterespondsToSelector:@selector(keyboardTool:buttonClick:)]){
[_toolDelegatekeyboardTool:selfbuttonClick:kKeyboardToolButtonTypeDone];
}
}
@end
相关文章推荐
- android源码 键盘消息处理机制
- IOS键盘响应及处理
- ios关于键盘遮挡处理
- IOS 键盘的显示与关闭,以及移动显示(UITextView处理完整版)(完美中文键盘输入避免触摸无效,做双重保障)
- iOS开发-自动处理键盘事件的第三方库 IQKeyboardManager
- iOS自动处理键盘事件的第三方库:IQKeyboardManager
- 第二人生的源码分析(二十四)人物向前走的键盘消息处理
- ios中键盘处理适合ipad 和iphone
- iOS 处理键盘遮挡TextField、TextView问题
- iOS键盘与文本框的处理(二)
- 第二人生的源码分析(二十四)人物向前走的键盘消息处理
- 有关ios自动滚动页面以显示被键盘挡住的编辑框的处理
- iOS自动处理键盘事件的第三方库:IQKeyboardManager
- 源码推荐(4.30):仿iOS简单计算器,简单涂鸦,自动监听键盘高度
- IOS开发中的键盘遮挡处理
- IOS研究之多个UITextField的键盘处理
- 处理iOS键盘通知
- iOS物理碰撞、唱吧音频处理、仿淘宝联动效果等源码
- IOS_DatePicker_PickerView_SegmentControl_键盘处理
- IOS开发Swift键盘收起,键盘挡住输入模框的处理