【问题标题】:How to show "Done" button on iOS number pad keyboard?如何在 iOS 数字键盘上显示“完成”按钮?
【发布时间】:2010-10-09 17:32:32
【问题描述】:

.numberPad 键盘类型上没有“完成”按钮。当用户在文本字段中输入完数字信息后,如何使数字键盘消失?

我可以使用默认键盘获得“完成”按钮,但用户必须切换到数字键才能输入数字。有没有办法在数字键盘上显示“完成”按钮?

【问题讨论】:

    标签: ios iphone user-input


    【解决方案1】:
     let pickerView = UIPickerView()
       
     var yearpickerToolbar: UIToolbar?
       
        func createPickerView() {
              
               pickerView.delegate = self
               textfield.inputView = pickerView }
       
       
         func dismissPickerView() {
               let toolBar = UIToolbar()
               toolBar.sizeToFit()
       
               toolBar.isUserInteractionEnabled = true
               textfield.inputAccessoryView = toolBar
               textfield.delegate = self
       
       
       yearpickerToolbar = UIToolbar()
               yearpickerToolbar?.autoresizingMask = .flexibleHeight
       
               //add buttons
               let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action:#selector(cancelBtnClicked(_:)))
               cancelButton.tintColor = UIColor.blue
               let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
               
               let doneButton = UIBarButtonItem(title: "Done", style: .plain , target: self, action: #selector(self.doneBtnClicked(_ :) ))
               doneButton.tintColor = UIColor.blue
       
               doneButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor:
       UIColor.black], for: .normal)
               cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor:
       UIColor.black], for: .normal)
               
               yearpickerToolbar?.items = [cancelButton, flexSpace, doneButton]
               textfield.inputAccessoryView = yearpickerToolbar }
       
       @objc func cancelBtnClicked(_ button: UIBarButtonItem?) {
               self.view.endEditing(true)
               
           }
       
           @objc func doneBtnClicked(_ button: UIBarButtonItem?) {
               self.view.endEditing(true)
           }
    

    【讨论】:

    • 您的答案可以通过添加有关代码的作用以及它如何帮助 OP 的更多信息来改进。
    【解决方案2】:

    我发现@user1258240's answer 非常简洁,因为这不像设置returnKeyType 属性那么简单。

    只是想为此贡献我自己的“可重用”方法:

    func SetDoneToolbar(field:UITextField) {
        let doneToolbar:UIToolbar = UIToolbar()
    
        doneToolbar.items=[
            UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil),
            UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: #selector(ViewController.dismissKeyboard))
        ]
    
        doneToolbar.sizeToFit()
        field.inputAccessoryView = doneToolbar
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        SetDoneToolbar(field: UITextField_1)
        SetDoneToolbar(field: UITextField_2)
        SetDoneToolbar(field: UITextField_3)
        SetDoneToolbar(field: UITextField_N)
    }
    

    【讨论】:

      【解决方案3】:

      如果您有多个数字字段,我建议继承 UITextField 以创建一个始终显示带有完成按钮的数字键盘的 NumericTextField。然后,只需将您的数字字段与 Interface Builder 中的此类关联,您就不需要在任何视图控制器中添加任何额外代码。以下是我在 Xcode 8.0 中使用的 Swift 3.0 类。

      class NumericTextField: UITextField {
         let numericKbdToolbar = UIToolbar()
      
          // MARK: Initilization
          required init?(coder aDecoder: NSCoder) {
              super.init(coder: aDecoder)
              self.initialize()
          }
      
          override init(frame: CGRect) {
              super.init(frame: frame)
              self.initialize()
          }
      
          // Sets up the input accessory view with a Done button that closes the keyboard
          func initialize()
          {
              self.keyboardType = UIKeyboardType.numberPad
      
              numericKbdToolbar.barStyle = UIBarStyle.default
              let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
              let callback = #selector(NumericTextField.finishedEditing)
              let donebutton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: callback)
              numericKbdToolbar.setItems([space, donebutton], animated: false)
              numericKbdToolbar.sizeToFit()
              self.inputAccessoryView = numericKbdToolbar
          }
      
          // MARK: On Finished Editing Function
          func finishedEditing()
          {
              self.resignFirstResponder()
          }
      }
      

      Swift 4.2

      class NumericTextField: UITextField {
          let numericKbdToolbar = UIToolbar()
      
          // MARK: Initilization
          required init?(coder aDecoder: NSCoder) {
              super.init(coder: aDecoder)
              self.initialize()
          }
      
          override init(frame: CGRect) {
              super.init(frame: frame)
              self.initialize()
          }
      
          // Sets up the input accessory view with a Done button that closes the keyboard
          func initialize()
          {
              self.keyboardType = UIKeyboardType.numberPad
      
              numericKbdToolbar.barStyle = UIBarStyle.default
              let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
              let callback = #selector(NumericTextField.finishedEditing)
              let donebutton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: callback)
              numericKbdToolbar.setItems([space, donebutton], animated: false)
              numericKbdToolbar.sizeToFit()
              self.inputAccessoryView = numericKbdToolbar
          }
      
          // MARK: On Finished Editing Function
          @objc func finishedEditing()
          {
              self.resignFirstResponder()
          }
      }
      

      【讨论】:

      • 我更喜欢你的子类解决方案。
      【解决方案4】:

      以下是对 Luda 答案的全面修改,并进行了以下更改:

      • 附件视图的大小会自动调整为应用程序框架的宽度

      • 避免使用已弃用的常量UIBarButtonItemStyleBordered

      • “完成”按钮被实例化为UIBarButtonSystemItemDone

      目前“完成”按钮位于附件视图的中心。您可以通过删除相关侧的空格将其定位在左侧或右侧。

      我省略了“取消”按钮,因为默认键盘也没有。如果您确实想要一个“取消”按钮,我建议您将其实例化为 UIBarButtonSystemItemCancel 并确保您没有丢弃文本字段中的原始值。 Luda 的答案中实现的“取消”行为,它用空白字符串覆盖了值,可能不是你想要的。

      - (void)viewDidLoad {
        [super viewDidLoad];
        float appWidth = CGRectGetWidth([UIScreen mainScreen].applicationFrame);
        UIToolbar *accessoryView = [[UIToolbar alloc]
                                    initWithFrame:CGRectMake(0, 0, appWidth, 0.1 * appWidth)];
        UIBarButtonItem *space = [[UIBarButtonItem alloc]
                                  initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                  target:nil
                                  action:nil];
        UIBarButtonItem *done = [[UIBarButtonItem alloc]
                                 initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                 target:self
                                 action:@selector(selectDoneButton)];
        accessoryView.items = @[space, done, space];
        self.valueField.inputAccessoryView = accessoryView;
      }
      
      - (void)selectDoneButton {
        [self.valueField resignFirstResponder];
      }
      

      有关构建附件视图的更多信息,请参阅custom views for data input 上的 Apple 文档。您可能还需要参考 UIToolbarUIBarButtonItem 上的参考页面。

      【讨论】:

      • [UIScreen mainScreen].applicationFrame 在 iOS 9 中已弃用。请使用 [UIScreen mainScreen].bounds
      【解决方案5】:

      更简单的解决方案

      - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
      { 
          [super touchesBegan:touches withEvent:event];
      
          [textViewInstance1 resignFirstResponder];
          [textViewInstance2 resignFirstResponder];
          [textField resignFirstResponder];
      }
      

      【讨论】:

        【解决方案6】:

        SWIFT 3.0 一种不同的风格,使用了以前的部分答案。

        func addToolbarToNumberPad()
        {
            let numberPadToolbar: UIToolbar = UIToolbar()
        
            numberPadToolbar.isTranslucent = true
            numberPadToolbar.items=[
                UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancelAction)),
                UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
                UIBarButtonItem(title: "Custom", style: .done, target: self, action: #selector(self.customAction)),
                UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.doneAction)),
            ]
        
            numberPadToolbar.sizeToFit()
        
            textField.inputAccessoryView = numberPadToolbar
        }
        
        func cancelAction()
        {
            textField.resignFirstResponder()
        }
        
        func customAction()
        {
            textField.resignFirstResponder()
        }
        
        func doneAction()
        {
            textField.resignFirstResponder()
        }
        
        override func viewDidLoad()
        {
            super.viewDidLoad()
        
            self.addToolbarToNumberPad()
        }
        

        【讨论】:

          【解决方案7】:

          使用扩展的 Swift 3 解决方案。如果您的应用程序中有多个数字 UITextField 对象,这是理想的选择,因为它可以灵活地为每个 UITextField 决定是否在 完成取消时执行自定义操作> 被点击。

          //
          //  UITextField+DoneCancelToolbar.swift
          //
          
          import UIKit
          
          extension UITextField {
              func addDoneCancelToolbar(onDone: (target: Any, action: Selector)? = nil, onCancel: (target: Any, action: Selector)? = nil) {     
                  let onCancel = onCancel ?? (target: self, action: #selector(cancelButtonTapped))
                  let onDone = onDone ?? (target: self, action: #selector(doneButtonTapped))
          
                  let toolbar: UIToolbar = UIToolbar()
                  toolbar.barStyle = .default
                  toolbar.items = [
                      UIBarButtonItem(title: "Cancel", style: .plain, target: onCancel.target, action: onCancel.action),
                      UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
                      UIBarButtonItem(title: "Done", style: .done, target: onDone.target, action: onDone.action)
                  ]
                  toolbar.sizeToFit()
          
                  self.inputAccessoryView = toolbar
              }
          
              // Default actions:  
              func doneButtonTapped() { self.resignFirstResponder() }
              func cancelButtonTapped() { self.resignFirstResponder() }
          }
          

          使用默认操作的使用示例:

          //
          // MyViewController.swift
          //
          
          @IBOutlet weak var myNumericTextField: UITextField! {
              didSet { myNumericTextField?.addDoneCancelToolbar() }
          }
          

          使用自定义完成操作的使用示例:

          //
          // MyViewController.swift
          //
          
          @IBOutlet weak var myNumericTextField: UITextField! {
              didSet { 
                  myNumericTextField?.addDoneCancelToolbar(onDone: (target: self, action: #selector(doneButtonTappedForMyNumericTextField))) 
              }
          }
          
          func doneButtonTappedForMyNumericTextField() { 
              print("Done"); 
              myNumericTextField.resignFirstResponder() 
          }
          

          【讨论】:

            【解决方案8】:

            Swift 2.2 / 我使用了 Dx_ 的答案。但是,我希望所有键盘都具有此功能。所以在我的基类中我放了代码:

            func addDoneButtonForTextFields(views: [UIView]) {
                for view in views {
                    if let textField = view as? UITextField {
                        let doneToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.bounds.size.width, 50))
            
                        let flexSpace = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
                        let done = UIBarButtonItem(title: "Done", style: .Done, target: self, action: #selector(dismissKeyboard))
            
                        var items = [UIBarButtonItem]()
                        items.append(flexSpace)
                        items.append(done)
            
                        doneToolbar.items = items
                        doneToolbar.sizeToFit()
            
                        textField.inputAccessoryView = doneToolbar
                    } else {
                        addDoneButtonForTextFields(view.subviews)
                    }
                }
            }
            
            func dismissKeyboard() {
                dismissKeyboardForTextFields(self.view.subviews)
            }
            
            func dismissKeyboardForTextFields(views: [UIView]) {
                for view in views {
                    if let textField = view as? UITextField {
                        textField.resignFirstResponder()
                    } else {
                        dismissKeyboardForTextFields(view.subviews)
                    }
                }
            }
            

            然后只需在 viewDidLoad 中调用 self.view.subviews 上的 addDoneButtonForTextFields(如果使用表格视图,则调用 willDisplayCell)将完成按钮添加到所有键盘。

            【讨论】:

              【解决方案9】:

              对于 Swift 2.2 我使用这个

              func addDoneButtonOnKeyboard() {
                  let doneToolbar: UIToolbar = UIToolbar(frame: CGRectMake(0, 0, self.view.bounds.size.width, 50))
              
                  let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
                  let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: #selector(DetailViewController.finishDecimalKeypad))
              
                  var items: [UIBarButtonItem]? = [UIBarButtonItem]()
                  items?.append(flexSpace)
                  items?.append(done)
              
                  doneToolbar.items = items
                  doneToolbar.sizeToFit()
                  self.productPrice.inputAccessoryView=doneToolbar
              }
              
              func finishDecimalKeypad() {
                  self.productPrice?.resignFirstResponder()
              }
              

              【讨论】:

                【解决方案10】:

                所有关于查找键盘视图并在第三行添加完成按钮的实现(这就是为什么 button.y = 163 b/c 键盘的高度为 216)都是脆弱的,因为 iOS 不断更改视图层次结构。例如以上代码均不适用于 iOS9。

                我认为通过 [[[UIApplication sharedApplication] windows] lastObject] 找到最上面的视图更安全,然后在其左下角添加按钮 doneButton.frame = CGRectMake(0, SCREEN_HEIGHT- 53, 106, 53);// 纵向模式

                【讨论】:

                  【解决方案11】:

                  如果我们只是告诉视图控制器的视图结束编辑,我们还可以使 “用户触摸其他地方” 解决方案更加简单:

                  -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
                   { 
                        [super touchesBegan:touches withEvent:event];
                  
                        [self.view endEditing:YES]; //YES ignores any textfield refusal to resign
                   }
                  

                  ...假设“触摸其他地方会关闭键盘”也是视图上任何其他可编辑字段的理想行为。

                  【讨论】:

                    【解决方案12】:

                    另一种解决方案。如果屏幕上有其他非数字键盘文本字段,那就完美了。

                    - (void)viewDidLoad
                    {
                        [super viewDidLoad];
                    
                        UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
                        numberToolbar.barStyle = UIBarStyleBlackTranslucent;
                        numberToolbar.items = @[[[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)]];
                        [numberToolbar sizeToFit];
                        numberTextField.inputAccessoryView = numberToolbar;
                    }
                    
                    -(void)cancelNumberPad{
                        [numberTextField resignFirstResponder];
                        numberTextField.text = @"";
                    }
                    
                    -(void)doneWithNumberPad{
                        NSString *numberFromTheKeyboard = numberTextField.text;
                        [numberTextField resignFirstResponder];
                    }
                    

                    【讨论】:

                    • 无疑是实现这一目标的最佳方式。明确是因为它遵守 Apple 严格的 HIG。
                    • 另一种解决方案非常脆弱,因为对屏幕键盘的任何图形更改都会破坏它。
                    • 如果有多个文本字段,如何确定正在编辑哪个 UITextField?
                    • 将 .h 中的 UITextField 定义为实例变量。
                    • @BenPotter 您可以为条形颜色设置 barTint,为文本设置色调颜色。您还可以在初始化程序之外创建 UIBarButton 项,并在那里显式设置它们的颜色。
                    【解决方案13】:

                    这是 Luda 对 Swift 的回答的改编:

                    在你的 UIViewController 子类的声明中放

                    let numberToolbar: UIToolbar = UIToolbar()
                    

                    在 ViewDidLoad 中放:

                        numberToolbar.barStyle = UIBarStyle.BlackTranslucent
                        numberToolbar.items=[
                            UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Bordered, target: self, action: "hoopla"),
                            UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil),
                            UIBarButtonItem(title: "Apply", style: UIBarButtonItemStyle.Bordered, target: self, action: "boopla")
                        ]
                    
                        numberToolbar.sizeToFit()
                    
                        textField.inputAccessoryView = numberToolbar //do it for every relevant textfield if there are more than one 
                    

                    并添加函数 hoopla 和 hoopla (随意选择其他名称,只需相应更改 ViewDidLoad 中的选择器名称

                    func boopla () {
                        textField.resignFirstResponder()
                    }
                    
                    func hoopla () {
                        textField.text=""
                        textField.resignFirstResponder()
                    }
                    

                    【讨论】:

                    • UIBarButtonItemStyle.Bordered 自 iOS 8.0 起已弃用。建议改为UIBarButtonItemStyle.Plain
                    • 选择器应该更新为:#selector(YourViewController.boopla)
                    • 乔尼和大卫可能是对的。我不再为 iOS 编程,所以我不关注这些变化。如果有人发布更新的解决方案,我会在编辑中引用它。
                    【解决方案14】:

                    如果您事先知道要输入的数字数量(例如 4 位 PIN 码),您可以在 4 次按键后自动关闭,根据我对这个类似问题的回答:

                    dismissing Number Pad

                    在这种情况下不需要额外的完成按钮。

                    【讨论】:

                      【解决方案15】:

                      我修改了 Bryan 的解决方案,使其更加健壮,这样它就可以很好地与可能出现在同一视图中的其他类型的键盘配合使用。这里有描述:

                      Create a DONE button on the iOS numpad UIKeyboard

                      我想在这里解释一下,但大部分是要查看的代码,不太适合这里

                      【讨论】:

                      • 这是我为 XCode 4.5 找到的最佳解决方案,它适用于 iOS 6.0。它在数字键盘上添加了一个 DONE 按钮。转到原始帖子以获取完成按钮图形。 neoos.ch/blog/…
                      【解决方案16】:

                      这是我遇到的最简单的解决方案。我从《开始 iOS 5 开发》一书中学到了这一点。

                      假设数字字段被称为numberField

                      1. ViewController中,添加如下方法:

                        -(IBAction)closeKeyboard:(id)sender;
                        
                      2. ViewController.m中,添加如下代码:

                        -(IBAction)closeKeyboard:(id)sender
                        {
                        
                             [numberField resignFirstResponder];
                        
                        }
                        
                      3. 返回nib文件。

                      4. 打开Utilities pan。
                      5. 打开Identity inspector下的Utilities pan。
                      6. 单击一次View(在 nib 文件中)。确保您没有单击视图中的任何项目。为了清楚起见,您应该在Identity inspector 中看到Class 下的UIView。
                      7. 将类从 UIView 更改为 UIControl。
                      8. 打开Connection Inspector
                      9. 单击并拖动Touch Down 并将箭头放在File Owner 图标上。 (仅供参考...文件所有者图标显示在View 的左侧,并显示为带有黄色框的空心立方体。)
                      10. 选择方法:closeKeyboard
                      11. 运行程序。

                      现在,当您单击View 背景上的任意位置时,您应该可以关闭键盘了。

                      希望这可以帮助您解决问题。 :-)

                      【讨论】:

                        【解决方案17】:

                        最简单的方法是:

                        创建自定义透明按钮并将其放在左下角,与空白处相同CGSizeUIKeyboardTypeNumberPad。在 textField becomeFirstResponder 上切换(显示/隐藏)此按钮,分别在按钮单击时。

                        【讨论】:

                          【解决方案18】:

                          我描述了一种适用于 iOS 4.2+ here 的解决方案,但在键盘出现后关闭按钮会淡入。这并不可怕,但也不理想。

                          上面链接的问题中描述的解决方案包括一个更优雅的关闭按钮的错觉,我淡化并垂直移动按钮以提供键盘和按钮一起关闭的外观。

                          【讨论】:

                            【解决方案19】:

                            这是最新的代码。只需包括 #import "UIViewController+NumPadReturn.h" 在您的视图控制器中。

                            这是.h

                            #import <Foundation/Foundation.h>
                            #import <UIKit/UIKit.h>
                            
                            @interface UIViewController (NumPadReturn)
                            
                            
                            
                            @end
                            

                            还有.m

                            #import "UIViewController+NumPadReturn.h"
                            
                            
                            @implementation UIViewController (NumPadReturn)
                            
                            -(void) viewDidLoad{
                                // add observer for the respective notifications (depending on the os version)
                                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)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)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)doneButton:(id)sender {
                                NSLog(@"doneButton");
                                [self.view endEditing:TRUE];
                            }
                            
                            
                            
                            @end
                            

                            【讨论】:

                            • 这似乎在模拟器上工作,但在设备上......我看不到完成按钮,当我点击空白空间时也没有任何反应......有什么想法吗?
                            • 哇,请不要使用此代码。您从一个类别中覆盖了类方法,这将导致您的 UIViewController 类中的“真实”viewDidLoad 等被忽略。
                            【解决方案20】:

                            UIKeyboardTypeNumberPad and missing return key 中的解决方案效果很好,但前提是屏幕上没有其他非数字键盘文本字段。

                            我使用该代码并将其转换为 UIViewController,您可以简单地对其进行子类化以使数字键盘工作。您需要从上面的链接中获取图标。

                            NumberPadViewController.h:

                            #import <UIKit/UIKit.h>
                            
                            @interface NumberPadViewController : UIViewController {
                                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;
                            
                            @end
                            

                            和 NumberPadViewController.m:

                            #import "NumberPadViewController.h"
                            
                            @implementation NumberPadViewController
                            
                            @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:@"DoneUp3.png"];
                                    self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"DoneDown3.png"];
                                } else {        
                                    self.numberPadDoneImageNormal = [UIImage imageNamed:@"DoneUp.png"];
                                    self.numberPadDoneImageHighlighted = [UIImage imageNamed:@"DoneDown.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 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];
                            }
                            
                            @end
                            

                            享受吧。

                            【讨论】:

                              【解决方案21】:

                              我见过的技巧是制作一个与整个视图大小相同的自定义透明按钮,然后在其单击方法中,让文本字段退出第一响应者。因此,用户可以单击字段外的任意位置来关闭键盘。

                              【讨论】:

                              • 除了回车键之外,我还做了这个。它使应用程序更加用户友好。我喜欢同时提供返回键和单击任意位置返回方法。
                              • 现在我们有了 UIGestureRecognizers,只需在主 viewcontroller 视图上设置一个轻击手势识别器,并让它发送 endEditing:YES 到它的视图。当在键盘外触摸时,这将关闭键盘可能服务的每个文本字段的键盘。
                              猜你喜欢
                              • 1970-01-01
                              • 2013-12-10
                              • 1970-01-01
                              • 1970-01-01
                              • 2011-03-02
                              • 2022-11-01
                              • 2016-03-19
                              • 1970-01-01
                              • 2021-07-20
                              相关资源
                              最近更新 更多