在IOS项目开发中,常遇到一些特殊的需要,比如需要特殊的字符或按钮显示在系统键盘的某个位置,那么这时候就要想到自定义一个按钮,来满足需要,在本人目前的项目开发中正好有这样一个需要:当用户输入密码后,点击键盘的Done按钮登录,但要求是系统键盘的Done 按钮是一个中文提示,如“登录”或“下一步”等。
通过阅读相关资料和测试,在前辈们的基础上做了一些修正和扩展,比如可以在多个文件中创建自定义的类(该类已经封装)对象,此外也利用Block进行方法回调,增强了封装性和健壮性。
具体实现步骤如下;
第一步,创建一个可重用的继承类,代码如下:
// 头文件
#import <UIKit/UIKit.h>
typedef void(^DoneActionBlock)(id); // 定义一个Block
@interface ChangeDoneKeyButtonTextField : UITextField
@property (nonatomic, retain) UIButton* doneButton;
@property (nonatomic, retain) NSString *buttonTitle;
@property (nonatomic, copy) DoneActionBlock doneEven;
@end
// 实现文件
#import “ChangeDoneKeyButtonTextField.h”
@implementation ChangeDoneKeyButtonTextField
@synthesize doneButton;
@synthesize buttonTitle;
@synthesize doneEven;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 注册UIKeyboardDidShowNotification通知的观察者为self
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification object:nil];
}
return self;
}
// 实现观察者的注册事件
-(void)keyboardDidHide:(NSNotification*)note{
if (self.doneButton) {
self.doneButton.hidden=YES;
}
}
- (void)keyboardDidShow:(NSNotification *)note {
//keyboard位于顶层窗口
NSInteger topWindow = [[[UIApplication sharedApplication] windows] count] – 1;
UIWindow *keyboard = [[[UIApplication sharedApplication] windows] objectAtIndex:topWindow];
// 在键盘第1次弹出时,创建按钮
if (self.doneButton == nil) {
self.doneButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.doneButton.hidden=YES;
// 向键盘中加入按钮
[keyboard addSubview:self.doneButton];
//定制按钮上面要显示的文字,也可以在创建该对象时自定义,本文只自定义了按钮上面的显示文字为:buttonTitle
[self.doneButton setTitle:buttonTitle forState:UIControlStateNormal]; // 设置按钮的位置在恰当的地方
[self.doneButton setFrame:CGRectMake(486/2.0, 876/2.0, 152/2.0, 80/2.0)];
[self.doneButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
self.doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
// 设置按钮背景图片
[self.doneButton setBackgroundImage:[UIImage imageNamed:@"DoneKeyBackground.png"] forState:UIControlStateNormal];
// 当按钮按下时,触发doneButton方法
[self.doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
}
if (self.editing) { // 只有当前输入框会显示done按钮
self.doneButton.hidden = NO;
} else {
self.doneButton.hidden = YES;
}
[keyboard bringSubviewToFront:self.doneButton];
}
//定制按钮的点击事件
- (void)doneButton:(id)sender {
self.doneButton.hidden=YES;
[self resignFirstResponder];
if (doneEven!=nil) { // block 回调
doneEven(sender);
}
}
- (void)dealloc
{
self.doneButton = nil;
self.doneEven = nil;
self.buttonTitle = nil;
[super dealloc];
}
第二步,在需要使用定制键盘的类中进行创建输入框对象,代码如下:
// 需要定制键盘文件的头文件
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITextFieldDelegate>
@end
// 需要定制键盘文件的实现文件
#import “ViewController.h”
#import “ChangeDoneKeyButtonTextField.h”
@interface ViewController ()
{
ChangeDoneKeyButtonTextField *changeDoneField;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 定制文本输入框
changeDoneField = [[[ChangeDoneKeyButtonTextField alloc] initWithFrame: CGRectMake(60, 60, 200, 30)] autorelease];
changeDoneField.borderStyle = UITextBorderStyleRoundedRect;
changeDoneField.keyboardType = UIKeyboardTypeDefault;
changeDoneField.returnKeyType = UIReturnKeyDone;
changeDoneField.delegate = self;
changeDoneField.placeholder = @”定制Done按钮键盘”;
changeDoneField.buttonTitle = @”登录”; //自定义按钮上面的文字,也可以是位置等该按钮的相关属性
changeDoneField.doneEven = ^(id sender){ //实现Block的回调
NSLog(@”begin logining”); //触发按钮的点击事件
};
[self.view addSubview:changeDoneField];
// 普通文本输入框
UITextField *testField = [[UITextField alloc] initWithFrame:CGRectMake(60, 110, 200, 30)];
testField.borderStyle = UITextBorderStyleRoundedRect;
testField.keyboardType = UIKeyboardTypeDefault;
testField.returnKeyType = UIReturnKeyDone;
testField.delegate = self;
testField.placeholder = @”系统默认键盘”;
[self.view addSubview:testField];
[testField release];
}
#pragma -mark textFieldDelegate
// 实现键盘的代理
- (void) textFieldDidBeginEditing:(UITextField *)textField {
if (textField == changeDoneField) {
changeDoneField.doneButton.hidden = NO;
}else {
changeDoneField.doneButton.hidden = YES;
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField == changeDoneField) {
changeDoneField.doneButton.hidden = YES;
}else {
changeDoneField.doneButton.hidden = NO;
}
}
@end
至此,自定义键盘代码全部完成,见下图一,在测试中也遇到一个问题,那就是如果用户点击了手写,那么定制的按钮同样会显示出来,见图二,这个问题还待研究,至此,定制常用键盘的功能,满足基本需要已经实现,在此次测试过程中,特别感谢同事李瑞勤的帮助。
附效果图:
图一
图二