为iphone的数字键盘添加done按键

ios4.0以前,尝试过修改UIKeyboardTypeNumberPad,为其添加done按键,那时只需要找到keyboardview,done作为subview添加上。后来发现这个方法在新的sdk中无效了,后来查到下面这种方式。

 

There are several issues which you must be aware of when working around the missing done button on the iPhone numeric keypad. Use of private API’s is frowned upon by apple and they can reject your application. Also a lot of the solutions out there don’t work very well for OS4. This solution works by drawing a button on top of the keypad and animating it off the screen when required. It also draws the text so you don’t have to rely on images.

 

Firstly add a header file call it something like NumberKeypadModController.h also create an M file. Add the follow code to your H file.

#import <Foundation/Foundation.h>

 

@protocol NumberKeypadModControllerDelegate <NSObject>

- (void) donePressed:(id)sender;

@end

/**
*    The class used to create the keypad
*/
@interface NumberKeypadModController : NSObject
{
NSTimer *fixKeyboardTimer;
UIButton *doneButton;
UITextField *currentTextField;
id<NumberKeypadModControllerDelegate> delegate;
int        showHideCounter;
BOOL    doneButtonShown;
BOOL    doneButtonShownRecently;
}

@property (nonatomic, retain) NSTimer *fixKeyboardTimer;

@property (nonatomic, retain) UIButton *doneButton;
@property (nonatomic, retain) UITextField *currentTextField;

@property (nonatomic, retain) id<NumberKeypadModControllerDelegate> delegate;

- (void)textFieldShouldBeginEditing:(UITextField *)textField;
- (void)textFieldDidBeginEditing:(UITextField *)textField;
- (void)textFieldShouldEndEditing:(UITextField *)textField;

- (void)resignedResponderWithView:(UIView*)textField;

@end

And your M file

#import “NumberKeypadModController.h”

 

@interface NumberKeypadModController (PrivateMethods)
- (void) addDoneToKeyboard;
- (void) removeDoneFromKeyboard;
- (void) donePressed;
@end

#define PRE_SLIDING_DELAY_DURATION        0.1
#define SLIDE_IN_ANIMATION_DURATION    0.2
#define SLIDE_OUT_ANIMATION_DURATION    0.15

#define USE_TEXTURED_BUTTON        0

@implementation NumberKeypadModController

@synthesize fixKeyboardTimer;

@synthesize doneButton;
@synthesize currentTextField;

@synthesize delegate;

- (id)init {
if (self = [super init]) {
self.fixKeyboardTimer = nil;
#if (USE_TEXTURED_BUTTON != 0)
self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 480, 105, 53);
if ([[[UIDevice currentDevice] systemVersion] hasPrefix:@”3″]) {
doneButton.frame = CGRectMake(0, 480, 105, 53);
[doneButton setImage:[UIImage imageNamed:@"DoneUp3.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown3.png"] forState:UIControlStateHighlighted];
} else {
[doneButton setImage:[UIImage imageNamed:@"DoneUp.png"] forState:UIControlStateNormal];
[doneButton setImage:[UIImage imageNamed:@"DoneDown.png"] forState:UIControlStateHighlighted];
}
#else
self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 480, 105, 53);
if ([[[UIDevice currentDevice] systemVersion] hasPrefix:@”3″])
doneButton.frame = CGRectMake(0, 480, 105, 53);
doneButton.titleLabel.font = [UIFont boldSystemFontOfSize:18];
[doneButton setTitleColor:[UIColor colorWithRed:60.0f/255.0f green:64.0f/255.0f blue:73.0f/255.0f alpha:1.0] forState:UIControlStateNormal];
[doneButton setBackgroundImage:[UIImage imageNamed:@"doneKeyDownBackground.png"] forState:UIControlStateHighlighted];
[doneButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[doneButton setTitle:@"DONE" forState:UIControlStateNormal];
#endif

[doneButton addTarget:self action:@selector(donePressed) forControlEvents:UIControlEventTouchUpInside];

self.currentTextField = nil;
self.delegate = nil;

showHideCounter = 0;
doneButtonShown = NO;
}
return self;
}

- (void)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField.keyboardType != UIKeyboardTypeNumberPad)
{
doneButton.hidden = YES;
doneButtonShownRecently = YES;
}
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField.keyboardType != UIKeyboardTypeNumberPad)
return;

//    NSLog(@”textFieldDidBeginEditing”);
self.currentTextField = textField; //Save reference to current textfield being edited

if (!doneButtonShownRecently)
{
if (fixKeyboardTimer)
[fixKeyboardTimer invalidate];
self.fixKeyboardTimer = [NSTimer timerWithTimeInterval:PRE_SLIDING_DELAY_DURATION target:self
selector:@selector(addDoneToKeyboard) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:fixKeyboardTimer forMode:NSDefaultRunLoopMode];
} else
{
[doneButton removeFromSuperview];
[self addDoneToKeyboard];
}
}

- (void)textFieldShouldEndEditing:(UITextField *)textField {
if (textField.keyboardType != UIKeyboardTypeNumberPad)
{
doneButtonShownRecently = YES;
[self performSelector:@selector(considerDoneButtonReallyHidden) withObject:nil afterDelay:SLIDE_OUT_ANIMATION_DURATION];
return;
}
[self removeDoneFromKeyboard];
}

- (void) textFieldDidEndEditing:(UITextField *)textField {
}

- (void)resignedResponderWithView:(UIView*)textField {
//    NSLog(@”resignedResponderWithView”);
[self removeDoneFromKeyboard];
}

- (void) addDoneToKeyboard {
//    NSLog(@”addDoneToKeyboard”);

doneButton.hidden =  NO;

//Add a button to the top, above all windows
NSArray *allWindows = [[UIApplication sharedApplication] windows];
NSUInteger topWindowIndex = [allWindows count] – 1;
UIWindow *topWindow = [allWindows objectAtIndex:topWindowIndex];

// check if top window is of keypad or else
NSString *topViewClassName = [NSString stringWithFormat:@"%@", [topWindow class]];
while (![topViewClassName isEqualToString:@"UITextEffectsWindow"] ) {
–topWindowIndex;

if(topWindowIndex < 0)
break;

topWindow = [allWindows objectAtIndex:topWindowIndex];
topViewClassName = [NSString stringWithFormat:@"%@", [topWindow class]];
}

if(topWindowIndex < 0) {
topWindowIndex = [allWindows count] – 1;
topWindow = [allWindows objectAtIndex:topWindowIndex];
}

if (doneButton.superview)
[doneButton removeFromSuperview];

[topWindow addSubview:doneButton];

if (!doneButtonShownRecently) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:SLIDE_IN_ANIMATION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
doneButton.frame = CGRectMake(0, 480-53, doneButton.frame.size.width, 53);
[UIView commitAnimations];
} else {
doneButton.frame = CGRectMake(0, 427, doneButton.frame.size.width, 53);
}

doneButtonShown = YES;
}

- (void) removeDoneFromKeyboard {
//    NSLog(@”removeDoneFromKeyboard”);

[fixKeyboardTimer invalidate];
self.fixKeyboardTimer = nil;

if (!doneButtonShownRecently) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:SLIDE_OUT_ANIMATION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
doneButton.frame = CGRectMake(0, 480, doneButton.frame.size.width, 53);
[UIView commitAnimations];
} else {
doneButton.frame = CGRectMake(0, 480, doneButton.frame.size.width, 53);
}

doneButtonShown = NO;
doneButtonShownRecently = YES;
[self performSelector:@selector(considerDoneButtonReallyHidden) withObject:nil afterDelay:SLIDE_OUT_ANIMATION_DURATION];
}

- (void)considerDoneButtonReallyHidden {
//    NSLog(@”considerDoneButtonReallyHidden”);
doneButtonShownRecently = NO;
}

- (void) donePressed {
[self.currentTextField resignFirstResponder];
if ([delegate respondsToSelector:@selector(donePressed:)])
[delegate performSelector:@selector(donePressed:) withObject:self.currentTextField];
}

- (void) dealloc {
[fixKeyboardTimer release];
[doneButton removeFromSuperview];
[doneButton release];
[delegate release];
[super dealloc];
}

@end

Now to your view header file add an import to NumberKeypadModController.h

Now its imple matter of adding a delegate to your interface and a property on the view your going to use the code. In your viewdidload add this code.

@interface YourViewController : UIViewController <UITextFieldDelegate, NumberKeypadModControllerDelegate> {

 

NumberKeypadModController *numberKeyPadModController;
IBOutlet UITextField *textFieldRow1;
}

@property(nonatomic,retain) NumberKeypadModController *numberKeyPadModController;
@property(nonatomic,retain) UITextField *textFieldRow1;

@end

And your m file.

#import “YourViewController.h”
#import “NumberKeypadModController.h”

 

@interface UIView (FindAndResignFirstResponder)
- (UIView*)findFirstResponder;
@end
@implementation UIView (FindAndResignFirstResponder)
- (UIView*)findFirstResponder {
if (self.isFirstResponder) {
[self resignFirstResponder];
return self;
}
for (UIView *subView in self.subviews) {
if ([subView findFirstResponder])
return subView;
}
return nil;
}
@end

@implementation YourViewController

@synthesize numberKeyPadModController;
@synthesize textFieldRow1;

- (void)viewDidLoad {
[super viewDidLoad];

self.numberKeyPadModController = [[[NumberKeypadModController alloc] init] autorelease];
numberKeyPadModController.delegate = self;

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doneButton:) name:@”DoneButtonPressed” object:nil];

textFieldRow1.delegate = self;
}

- (void)doneButtonPressed:(UITextField*)sender{
if ([textFieldRow1 isEditing]) {
[textFieldRow1 resignFirstResponder];
}
}

- (void) donePressed:(id)sender {
UIView* firstResponder = [self.view findFirstResponder];
[firstResponder resignFirstResponder];
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[numberKeyPadModController textFieldShouldBeginEditing:textField];

return YES;
}

- (void) textFieldDidBeginEditing:(UITextField *)textField {
[numberKeyPadModController textFieldDidBeginEditing:textField];
}

- (BOOL) textFieldShouldEndEditing:(UITextField *)textField {
[numberKeyPadModController textFieldShouldEndEditing:textField];
return YES;
}

-(void)touchesBegan(NSSet *)touches withEvent:(UIEvent *)event {
UIView* firstResponder = [self.view findFirstResponder];
[firstResponder resignFirstResponder];
[numberKeyPadModController resignedResponderWithView:firstResponder];

[super touchesBegan:touches withEvent:event];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (void)dealloc {
[super dealloc];
}

@end

Now in interface builder add a UITextField and assign the outlet, save and run.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值