【问题标题】:How to dismiss number pad keyboard by tapping anywhere如何通过点击任意位置来关闭数字键盘
【发布时间】:2011-10-22 21:29:01
【问题描述】:

我想知道在点击数字键盘外的任何位置时关闭数字键盘键盘的最简单代码。这是一个在文本字段中输入数字的简单应用程序,然后用户可以在用户在文本字段中输入完数字后关闭键盘。谢谢! :)

【问题讨论】:

标签: iphone ios xcode numbers uitextfield


【解决方案1】:

斯威夫特 5

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
           self.view.endEditing(true)
           return true
 }

【讨论】:

    【解决方案2】:

    对于 swift 3/4 我喜欢这种情况:

    1. View Controller 是 UITextFieldDelegate 的子类
    2. 在viewDidLoad函数中,必须设置yourPhonePadField.delegate = self
    3. 并覆盖这个函数:

      override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         self.view.endEditing(true) 
      }
      

    【讨论】:

      【解决方案3】:

      您可以通过在插座上放置didSet 并在此处附加您的 inputAccessoryView 来很好地实现@mbm 的答案:

      Swift 代码:

        @IBOutlet var input: UITextField! { didSet {
          let toolbar = UIToolbar(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 0, height: 44)))
          toolbar.items = [
            UIBarButtonItem(barButtonSystemItem: .done, target: self.input,
              action: #selector(resignFirstResponder))
          ]
          input.inputAccessoryView = toolbar
        }}
      

      在 xcode 8 / iOS 10 中它最终看起来像这样:

      【讨论】:

      • 被低估的答案。我喜欢它。
      • 最佳解决方案!
      【解决方案4】:

      对于 Swift 使用下面的代码

      override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
       {
             textFiled.resignFirstResponder()
       }
      

      查看关注Link的最新更新

      【讨论】:

      • 谢谢。很高兴在这里看到一个 Swift 的答案
      • touchesBegan 已更新。如果您有问题,请查看stackoverflow.com/questions/28771896/…。
      • 现在函数读取override func touchesBegan(touches: Set&lt;UITouch&gt;, withEvent event: UIEvent?)
      【解决方案5】:

      您必须使用 UITapGestureRecognizer 来实现这一点。

      UITapGestureRecognizer *tapToDismiss = [[UITapGestureRecognizer alloc]initWithTarget: self action: @selector (dismissNumberKeyBoard:)];
      

      然后在您的 dismissNumberKeyboard 方法中,

      -(Void)dismissNumberKeyboard : (id)sender {
      
         [yourTextField resignFirstResponder];
      
      }
      

      编码愉快!

      【讨论】:

        【解决方案6】:

        对于 Swift,通过点击文本字段外的任意位置来关闭所有文本字段的键盘的最简单方法是:

        override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
        {
            self.view.endEditing(true)
        }
        

        【讨论】:

          【解决方案7】:

          这里有很多答案,但仍然不得不使用 XCode 5 来解决这个问题。 读这个: https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizer_basics/GestureRecognizer_basics.html

          为您的 UIScrollView 添加一个点击手势识别器。将其委托设置为视图控制器。

          添加这个方法:

          - (IBAction)tappedSomewhere:(id)sender {
              [self.view endEditing:YES];
          }
          

          到您的 UIScrollView 实现代码,并通过控制单击并拖动到实现代码将其关联到 Tap Gesture Recognizer。

          为我工作。

          【讨论】:

            【解决方案8】:

            我尝试在此处实施一些解决方案,但发现它们存在一些问题。值得注意的是,我的UIView 包含一个UIScrollView,它似乎会拦截触摸。

            当失败时,我认为“在任何地方敲击”是一种未指定的行为,需要用户猜测如何关闭键盘,而不是给他们明确的指导。

            此外,我在应用中显示的每个其他键盘上都有一个“返回”或“完成”按钮,因此我决定为用户提供一种简单、直观、明确指定的方式来关闭带有数字的键盘与其他正在使用的键盘解除机制一致的 Pad。

            我意识到这不是 OP 的具体要求,但我相信它是比“点击任意位置”请求更好的解决方案(而且很容易实现!)。

            以下代码在我的UIViewController 中作为-viewDidLoad 的一部分调用。

            // My app is restricted to portrait-only, so the following works
            UIToolbar *numberPadAccessoryInputView      = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0f)];
            
            // My app-wide tint color is a gold-ish color, so darkGray contrasts nicely
            numberPadAccessoryInputView.barTintColor    = [UIColor darkGrayColor];
            
            // A basic "Done" button, that calls [self.textField resignFirstResponder]
            UIBarButtonItem *numberPadDoneButton        = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self.textField action:@selector(resignFirstResponder)];
            
            // It's the only item in the UIToolbar's items array
            numberPadAccessoryInputView.items           = @[numberPadDoneButton];
            
            // In case the background of the view is similar to [UIColor darkGrayColor], this
            // is put as a contrasting edge line at the top of the UIToolbar
            UIView *topBorderView                       = [[UIView alloc] initWithFrame:CGRectMake(0, 0, numberPadAccessoryInputView.frame.size.width, 1.0f)];
            topBorderView.backgroundColor               = [UIColor whiteColor];
            [numberPadAccessoryInputView addSubview:topBorderView];
            
            // Make it so that this UITextField shows the UIToolbar
            self.textField.inputAccessoryView           = numberPadAccessoryInputView;
            

            这样,键盘顶部添加了一个漂亮、漂亮、直观的控件,可以清楚地指示用户在完成文本输入后应该如何继续。

            我仍然相信 Apple 应该为这个键盘提供一个“完成”按钮(就像 Janak Nirmal 发布的链接一样),但这对我来说是最优雅的非 Apple 解决方案。

            【讨论】:

              【解决方案9】:

              在 xcode 5 中使用 Tap Gesture Recognizer 并在 .h 中声明并选择一个名称并在 .m 中声明

              - (IBAction)backgroundTap:(id)sender {
                  [self.view endEditing: YES];
              }
              

              【讨论】:

                【解决方案10】:

                如果您制作了自定义数字键盘或其他弹出框,另一种解决方案是在 UIView 的 init 中使用手势识别器,如下所示:

                tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
                tapper.cancelsTouchesInView = NO;
                [self addGestureRecognizer:tapper];
                
                 _yourViewController = [[CustomViewController alloc] init];
                _yourPopoverController = [[UIPopoverController alloc] initWithContentViewController:_yourViewController];
                _yourPopoverController.popoverContentSize = CGSizeMake(550, 300);
                _yourViewController.delegate = self;
                

                如果可见,则让 handleSingleTap 关闭弹出框并关闭编辑:

                - (void)handleSingleTap:(UITapGestureRecognizer *) sender
                {
                    if ([_yourPopoverController isPopoverVisible]) {
                        [_yourPopoverController dismissPopoverAnimated:YES];
                    }
                
                    [self endEditing:YES];
                }
                

                【讨论】:

                  【解决方案11】:

                  试试这个方法,

                  -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
                  {
                     [self.view endEditing:YES];
                  }
                  

                  现在点击任意位置,看到键盘将关闭。 :-)

                  【讨论】:

                  • 我不知道我是怎么错过这个 API 调用的,但这是这里最正确的答案。
                  【解决方案12】:

                  触摸背景关闭键盘

                  如果您还没有到 Xcode,请转到 Xcode。我们需要在控制器类中再添加一个动作。将以下行添加到您的 Control_FunViewController.h 文件中:

                  #import <UIKit/UIKit.h>
                  @interface Control_FunViewController : UIViewController { 
                  UITextField *nameField;
                  UITextField *numberField;
                  }
                   @property (nonatomic, retain) IBOutlet UITextField *nameField; ]
                  @property (nonatomic, retain) IBOutlet UITextField *numberField; 
                  - (IBAction)textFieldDoneEditing:(id)sender; 
                  - (IBAction)backgroundTap:(id)sender; 
                  @end  
                  

                  保存头文件;切换到实现文件,并添加此代码,该代码只是告诉两个文本字段在有第一响应者状态时产生第一响应者状态。在不是第一响应者的控件上调用 resignFirstResponder 是完全安全的,因此我们可以在两个文本字段上安全地调用它,而无需检查其中一个是否是第一响应者。

                  - (IBAction)backgroundTap:(id)sender { 
                  [nameField resignFirstResponder]; 
                  [numberField resignFirstResponder];
                  }
                  

                  提示 保存此文件,然后返回 Interface Builder。我们现在需要更改 nib 视图的底层类。如果您查看 nib 的主窗口,您会看到该视图中有三个图标。第三个,称为 View,是我们 nib 的主视图,它包含所有其他控件和视图作为子视图。 单击名为 View 的图标,它代表我们 nib 的容器视图。按 ␣4 调出身份检查器。这是我们可以在 Interface Builder 中更改任何对象实例的底层类的地方。

                  在编写代码时,您会经常在头文件和实现文件之间切换。幸运的是,Xcode 有一个组合键可以让你在这些文件之间快速切换。默认组合键是 ␣␣␣(选项命令向上箭头),尽管您可以使用 Xcode 的首选项将其更改为您想要的任何内容。76

                  标签为 Class 的字段当前为 UIView。将其更改为读取 UIControl。所有能够触发动作方法的控件都是 UIControl 的子类,因此通过更改底层类,我们刚刚赋予该视图触发动作方法的能力。您可以通过按 ␣2 调出连接检查器来验证这一点。

                  从 Touch Down 事件拖到 File’s Owner 图标,然后选择 backgroundTap: 操作。现在,在没有活动控件的情况下触摸视图中的任何位置都会触发我们的新操作方法,这将导致键盘缩回。

                  注意 保存笔尖,让我们回去试试。再次编译并运行您的应用程序。这一次,键盘不仅会在点击 Done 按钮时消失,而且在您单击非活动控件的任何位置时也会消失,这是您的用户所期望的行为。

                  【讨论】:

                  • 感谢 rptwsthi 先生! :) 感谢您的帖子。
                  【解决方案13】:

                  如果尚未将文本字段声明为实例变量或属性,并实现如下简单方法:

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

                  会很好。

                  【讨论】:

                  • 感谢您的惠顾。这是迄今为止关闭键盘的最简单方法。 :)
                  • 如果用户点击另一个控件(而不是背景),效果就不太好了。
                  • 外接蓝牙键盘时,有什么办法可以处理数字键盘的消失?在外部键盘上点击返回键不会触发 textFieldShouldReturn 委托,因为数字键盘没有返回键
                  【解决方案14】:

                  只要做一个像这样的简单函数..

                      -(IBAction)hideKeyboard:(id)Sender
                  {
                      [_textValue resignFirstResponder];
                  }
                  

                  现在转到您的 nib 文件并将此函数与带有 didEndOnExit 的文本字段连接起来,您就可以开始了。现在,当您在文本字段外单击时,键盘将自行隐藏。

                  【讨论】:

                    【解决方案15】:

                    我必须为我的 UITableView(里面出现一个 UITextField)实现一个类似的 UX。首先,在 tableView 中添加一个UITapGestureRecognizer。这将开始捕获从现在开始发生的所有点击。

                    UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
                            [self.tableView addGestureRecognizer:tapGestureRecognizer];
                            [tapGestureRecognizer release];
                    

                    但是,副作用是,当用户点击 UITextField 本身时,您不想关闭键盘。所以,这种情况必须加以区分。

                    handleTap 方法实现看起来像-

                    /*
                     In the text editing mode, listens to all taps occurring on the table view to exit the mode. There are two special cases to consider:
                     a) Text field's clear button
                     b) Text field
                     */
                    -(void)handleTap:(UITapGestureRecognizer*)tapRecognizer 
                    {
                        if(tapRecognizer.state == UIGestureRecognizerStateEnded) 
                        {
                    
                                //Figure out where the user tapped
                                CGPoint p = [tapRecognizer locationInView:textField];
                                CGRect textFieldBounds = textField.bounds;
                                CGRect clearButtonBounds = CGRectMake(textFieldBounds.origin.x + textFieldBounds.size.width - 44, textFieldBounds.origin.y, 44, textFieldBounds.size.height); 
                    
                                if(CGRectContainsPoint(clearButtonBounds, p))
                                    textField.text = @"";
                    
                                if(CGRectContainsPoint(textFieldBounds, p))
                                    return;
                    
                            [textField resignFirstResponder];
                            //remove the tap gesture recognizer that was added.
                            for(id element in self.tableView.gestureRecognizers)
                            {
                            if([element isKindOfClass:[UITapGestureRecognizer class]])
                            {
                                [self.tableView removeGestureRecognizer:element];
                            }
                            }
                        }
                            [self commitNewText];
                        }
                    }
                    

                    HTH。如果你喜欢,请将其标记为答案。

                    -阿克谢

                    【讨论】:

                      【解决方案16】:

                      通常,当用户点击“取消”按钮时,我会使用它来关闭键盘 -

                      - (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar
                      {
                          NSLog(@"cancel clicked");
                          [searchBar resignFirstResponder]; // dismiss keyboard
                          return;
                      }
                      

                      如果您想在用户触摸键盘区域外的任何位置时执行此操作,则需要实现 touchesEnded 并将此代码放在那里 -

                      /* Delegate for when touch ends.  */
                      -(void)touchesEnded:(NSSet *)touches 
                                withEvent:(UIEvent *)event
                      {
                          [searchBar resignFirstResponder];
                      }
                      

                      我自己没有尝试过,但我认为这应该可以解决问题......

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2014-07-30
                        • 2020-02-02
                        • 2019-06-30
                        • 1970-01-01
                        • 2023-03-08
                        • 2017-01-15
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多