完成按钮仅适用于数字键盘
Posted
技术标签:
【中文标题】完成按钮仅适用于数字键盘【英文标题】:done button only for numberpad keyboard 【发布时间】:2011-11-23 08:44:49 【问题描述】:我正在开发 iPhone 应用程序。我在一个视图中有四个文本字段。在这四个文本字段中,我有一个文本字段,其中将使用数字键盘。但是在数字键盘上没有返回键。所以我使用以下代码以编程方式添加了“完成”按钮。
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];
- (void)addButtonToKeyboard
// create custom button
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
doneButton.frame = CGRectMake(0, 163, 106, 53);
doneButton.adjustsImageWhenHighlighted = NO;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.0)
[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];
[doneButton addTarget:self action:@selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
// locate keyboard view
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
UIView* keyboard;
for(int i=0; i<[tempWindow.subviews count]; i++)
keyboard = [tempWindow.subviews objectAtIndex:i];
// keyboard found, add the button
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2)
if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
[keyboard addSubview:doneButton];
else
if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
[keyboard addSubview:doneButton];
- (void)keyboardWillShow:(NSNotification *)note
// if clause is just an additional precaution, you could also dismiss it
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 3.2)
[self addButtonToKeyboard];
- (void)keyboardDidShow:(NSNotification *)note
// if clause is just an additional precaution, you could also dismiss it
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2)
[self addButtonToKeyboard];
- (void)doneButton:(id)sender
NSLog(@"doneButton");
NSLog(@"Input: %@", contactno.text);
[contactno resignFirstResponder];
这个特定的文本字段很好。但是这个按钮也可以添加到其余的文本字段中。如何为其他文本字段取消隐藏此按钮。
非常感谢。
【问题讨论】:
cocoacontrols.com/platforms/ios/controls/amkeyboardnumberpad 看看这个实现,对我来说效果很好 这是一件非常糟糕的事情。如果键盘的实现发生变化,它很容易中断。它不适用于 iPad,尤其不适用于 iOS 5 中的拆分键盘。 【参考方案1】:求求求求求求求求求求求求求求求求求求求求你不要这样做了。这太可笑地脆弱了。考虑一下:
如果数字键盘的布局发生变化怎么办? 如果按键颜色发生变化怎么办? 如果键盘的实现发生变化,使其不再是索引 1 处的窗口,该怎么办? 如果键盘和外围主机的实现发生变化,导致内省描述中断怎么办? 如果您在键盘布局完全不同的 iPad 上运行此程序怎么办?这些只是将您的 UI 融入私有视图层次结构所带来的众多问题中的几个。
不要这样做。
这里有 2 个替代方案:
使用每个UIResponder
(以及每个UIView
)的-inputAccessoryView
属性来定义一个带有“完成”按钮的UIToolbar
。 inputAccessoryView
将在键盘动画进出时位于键盘上方。
在整个 UI 上添加一个透明的UIView
,用于捕获点击事件并导致键盘关闭
【讨论】:
3.提交一个错误报告,要求 Apple 已经在数字键盘上添加一个该死的完成按钮。 @Maulik 说服您的客户有更好的方法来做到这一点 非常有帮助。正是我需要的线索。谢谢! 对于 inputAccessoryView 选项,请参见此处的示例:iosinfopot.blogspot.com/2013/09/…【参考方案2】:我想您可以保留一个全局变量 UITextField * selectedTextField
作为指向用户当前选择的 textField 的指针(弱引用)。还将IBOutlets
存储到视图上的所有UITextField
对象(强引用)。然后将整个 addButtonToKeyboard
正文包裹在一个大 if 子句中:
if (self.selectedTextField == self.contactNumberTextField)
// ... add button
您需要设置UITextField
委托方法
- (void)textFieldDidBeginEditing:(UITextField *)textField;
知道当前选中的是哪个textField。
事实上,我认为您甚至可以在没有插座的情况下使用selectedTextField.keyboardType
属性来做到这一点,但话又说回来,您可能已经拥有插座,因为您需要它们从中读取用户输入。
希望这会有所帮助!
【讨论】:
【参考方案3】:将此代码放入您的项目中并设置文本字段的 iboutlet。它也有一些未使用的方法,但您可以使用它来选择完成按钮。然后您将删除未使用的方法。这仅用于完成按钮数字键盘
.H 文件
@interface aaaViewController : UIViewController
IBOutlet UITextField *txthello;
UIImage *numberPadDoneImageNormal;
UIImage *numberPadDoneImageHighlighted;
UIButton *numberPadDoneButton;
@property (nonatomic, retain) UIImage *numberPadDoneImageNormal;
@property (nonatomic, retain) UIImage *numberPadDoneImageHighlighted;
@property (nonatomic, retain) UIButton *numberPadDoneButton;
.M 文件
- (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];
【讨论】:
以上是关于完成按钮仅适用于数字键盘的主要内容,如果未能解决你的问题,请参考以下文章