您的位置:首页 > 移动开发 > IOS开发

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: