我想在 iPhone 数字键盘上添加一个完成按钮。左下角甚至还有一个方便的空间来放置这样一个按钮。
以前,我使用了与问题 584538和Luzian Scherrer 的优秀博客文章中描述的技巧类似的技巧,但在 iOS 4 中停止工作。我可以通过创建自定义 inputView 来做到这一点,但我更喜欢扩展 Apple 的键盘而不是写我自己的。
有没有一种新方法可以向标准键盘添加视图?有人为此发布了 OSS inputView 吗?还有其他方法吗?
我想在 iPhone 数字键盘上添加一个完成按钮。左下角甚至还有一个方便的空间来放置这样一个按钮。
以前,我使用了与问题 584538和Luzian Scherrer 的优秀博客文章中描述的技巧类似的技巧,但在 iOS 4 中停止工作。我可以通过创建自定义 inputView 来做到这一点,但我更喜欢扩展 Apple 的键盘而不是写我自己的。
有没有一种新方法可以向标准键盘添加视图?有人为此发布了 OSS inputView 吗?还有其他方法吗?
您可以添加inputAccessoryView
“应用”和“取消”按钮,然后关闭数字键盘。
- (void)viewDidLoad
{
[super viewDidLoad];
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelNumberPad)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:@"Apply" style:UIBarButtonItemStyleDone target:self action:@selector(doneWithNumberPad)],
nil];
numberTextField.inputAccessoryView = numberToolbar;
}
-(void)cancelNumberPad{
[numberTextField resignFirstResponder];
numberTextField.text = @"";
}
-(void)doneWithNumberPad{
NSString *numberFromTheKeyboard = numberTextField.text;
[numberTextField resignFirstResponder];
}
我得到了这个工作。请参阅此处的代码:http: //gist.github.com/454844
有两个问题:
UIKeyboardWillShowNotification
在键盘视图存在之前发送,但是如果您安排代码在下一个运行循环传递中运行,它们确实存在。因此,您不必DidShow
为视觉上不那么令人愉悦而烦恼。
在 iOS 4 上,UIKeyboard
视图位于视图层次结构的其他位置。
Luzian Scherrer 的博客文章 中描述的技术确实适用于 iOS 4.0。
我将按钮添加到键盘的代码失败了,因为它是从textFieldDidBeginEditing:
委托方法调用的,该方法(在 4.0 中)是在创建键盘窗口的子视图之前调用的。我通过在观察到时调用我的代码解决了这个问题UIKeyboardWillShowNotification
,这发生得够晚了。
我重构了代码,放到了github上。
我已将此作为错误提交给 Apple。Interface Builder 允许开发人员为数字键盘类型的键盘指定返回键类型。错误号 8759674。
苹果随后表示,此问题之前已记录为 Bug ID# 5885964,他们关闭了 8759674。
您可以使用此键盘通知代码在数字键盘上制作完成按钮。您只需在最后下载 done.png 图像。
在 .h 文件中
{ //Keyboard Hide
UIImage *numberPadDoneImageNormal;
UIImage *numberPadDoneImageHighlighted;
UIButton *numberPadDoneButton;
}
@property (nonatomic, retain) UIImage *numberPadDoneImageNormal;
@property (nonatomic, retain) UIImage *numberPadDoneImageHighlighted;
@property (nonatomic, retain) UIButton *numberPadDoneButton;
- (IBAction)numberPadDoneButton:(id)sender;
在 .m 文件中
@synthesize numberPadDoneImageNormal;
@synthesize numberPadDoneImageHighlighted;
@synthesize numberPadDoneButton;
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
if ([super initWithNibName:nibName bundle:nibBundle] == nil)
return nil;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0) {
self.numberPadDoneImageNormal = [UIImage imageNamed:@"NumberDone.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"NumberDone.png"];
} else {
self.numberPadDoneImageNormal = [UIImage imageNamed:@"NumberDone.png"];
self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"NumberDone.png"];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Add listener for keyboard display events
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
}
// Add listener for all text fields starting to be edited
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFieldDidBeginEditing:)
name:UITextFieldTextDidBeginEditingNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextFieldTextDidBeginEditingNotification
object:nil];
[super viewWillDisappear:animated];
}
- (UIView *)findFirstResponderUnder:(UIView *)root {
if (root.isFirstResponder)
return root;
for (UIView *subView in root.subviews) {
UIView *firstResponder = [self findFirstResponderUnder:subView];
if (firstResponder != nil)
return firstResponder;
}
return nil;
}
- (UITextField *)findFirstResponderTextField {
UIResponder *firstResponder = [self findFirstResponderUnder:[self.view window]];
if (![firstResponder isKindOfClass:[UITextField class]])
return nil;
return (UITextField *)firstResponder;
}
- (void)updateKeyboardButtonFor:(UITextField *)textField {
// Remove any previous button
[self.numberPadDoneButton removeFromSuperview];
self.numberPadDoneButton = nil;
// Does the text field use a number pad?
if (textField.keyboardType != UIKeyboardTypeNumberPad)
return;
// If there's no keyboard yet, don't do anything
if ([[[UIApplication sharedApplication] windows] count] < 2)
return;
UIWindow *keyboardWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
// Create new custom button
self.numberPadDoneButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.numberPadDoneButton.frame = CGRectMake(0, 163, 106, 53);
self.numberPadDoneButton.adjustsImageWhenHighlighted = FALSE;
[self.numberPadDoneButton setTitle:@"Return" forState:UIControlStateNormal];
[self.numberPadDoneButton setFont:[UIFont boldSystemFontOfSize:18]];
[self.numberPadDoneButton setTitleColor:[UIColor colorWithRed:77.0f/255.0f green:84.0f/255.0f blue:98.0f/255.0f alpha:1.0] forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageNormal forState:UIControlStateNormal];
[self.numberPadDoneButton setImage:self.numberPadDoneImageHighlighted forState:UIControlStateHighlighted];
[self.numberPadDoneButton addTarget:self action:@selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
// Locate keyboard view and add button
NSString *keyboardPrefix = [[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2 ? @"<UIPeripheralHost" : @"<UIKeyboard";
for (UIView *subView in keyboardWindow.subviews) {
if ([[subView description] hasPrefix:keyboardPrefix]) {
[subView addSubview:self.numberPadDoneButton];
[self.numberPadDoneButton addTarget:self action:@selector(numberPadDoneButton:) forControlEvents:UIControlEventTouchUpInside];
break;
}
}
}
- (void)textFieldDidBeginEditing:(NSNotification *)note {
[self updateKeyboardButtonFor:[note object]];
}
- (void)keyboardWillShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (void)keyboardDidShow:(NSNotification *)note {
[self updateKeyboardButtonFor:[self findFirstResponderTextField]];
}
- (IBAction)numberPadDoneButton:(id)sender {
UITextField *textField = [self findFirstResponderTextField];
[textField resignFirstResponder];
}
- (void)dealloc {
[numberPadDoneImageNormal release];
[numberPadDoneImageHighlighted release];
[numberPadDoneButton release];
[super dealloc];
}
我创建了一个版本来启用数字键盘的水平版本...插入 Luzian Scherrer 的博客中描述的技术并添加两个额外的 png(此处未包括),并将“isLandscape”布尔值添加到“didRotateFromInterfaceOrientation”方法中。 .
@interface AlarmController ()
{
CGRect doneButtnRectVert;
CGRect doneButtnRectHorz;
CGRect doneButtnRect;
UIImage* DoneUpVert;
UIImage* DoneDownVert;
UIImage* DoneUpHorz;
UIImage* DoneDownHorz;
UIImage* DoneUp;
UIImage* DoneDown;
UIButton *oldDoneButton;
}
@end
//---------------------------------------------------------------------------
- (void)viewDidUnload
{
NSLog(@"viewDidUnload AlarmController");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification object:nil];
[super viewDidUnload];
}
//---------------------------------------------------------------------------
- (void)addButtonToKeyboard
{
NSLog(@"addButtonToKeyboard AlarmController");
if (isLandscape)
{
doneButtnRect = doneButtnRectHorz;
DoneUp = DoneUpHorz;
DoneDown = DoneDownHorz;
} else {
doneButtnRect = doneButtnRectVert;
DoneUp = DoneUpVert;
DoneDown = DoneDownVert;
}
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = doneButtnRect;
doneButton.adjustsImageWhenHighlighted = NO;
[doneButton setImage:DoneUp forState:UIControlStateNormal];
[doneButton setImage:DoneDown forState:UIControlStateHighlighted];
[doneButton addTarget:self action:@selector(done:) forControlEvents:UIControlEventTouchUpInside];
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
{
keyboard = [tempWindow.subviews objectAtIndex:i];
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
{
if (oldDoneButton) [oldDoneButton removeFromSuperview];
[keyboard addSubview:doneButton];
}
}
oldDoneButton = doneButton;
}
//---------------------------------------------------------------------------
- (void)keyboardDidShow:(NSNotification *)note
{
NSLog(@"keyboardDidShow AlarmController");
[self addButtonToKeyboard];
}
#pragma mark -
#pragma mark meaty area...
//---------------------------------------------------------------------------
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(@"textFieldDidEndEditing AlarmController");
oldDoneButton = nil;
}
//---------------------------------------------------------------------------
- (void)viewDidLoad
{
NSLog(@"viewDidLoad AlarmController");
[super viewDidLoad];
doneButtnRectVert = CGRectMake(0, 163, 106, 53);
doneButtnRectHorz = CGRectMake(0, 122, 159, 40);
DoneUpVert = [UIImage imageNamed:@"DoneUp3.png"];
DoneDownVert = [UIImage imageNamed:@"DoneDown3.png"];
DoneUpHorz = [UIImage imageNamed:@"DoneUpHor.png"];
DoneDownHorz = [UIImage imageNamed:@"DoneDnHor.png"];
doneButtnRect = doneButtnRectVert;
DoneUp = DoneUpVert;
DoneDown = DoneDownVert;
oldDoneButton = nil;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil];
}