完成按钮仅适用于数字键盘

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 属性来定义一个带有“完成”按钮的UIToolbarinputAccessoryView 将在键盘动画进出时位于键盘上方。

    在整个 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];

【讨论】:

以上是关于完成按钮仅适用于数字键盘的主要内容,如果未能解决你的问题,请参考以下文章

仅类似于电话的数字软键盘

Xamarin.Forms.UWP 数字键盘仅在软键盘上

为啥 Slime 检查仅适用于鼠标单击而不适用于键盘命令?

矩阵键盘 4*4 arduino

键盘可以完成和取消按钮吗?

在动态 UITableView 中关闭 iPhone 键盘