如何通过点击任意位置来关闭数字键盘

发布于 2024-11-28 17:20:30 字数 94 浏览 0 评论 0原文

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

I'd like to know the simplest code to dismiss the number pad keyboard when tapping anywhere outside the number pad. It's a simple application to input a number inside a text field and then a user can dismiss the keyboard after the user finishes typing the numbers on the text field. Thanks! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

深海蓝天 2024-12-05 17:20:31

对于 Swift,请使用以下代码

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

查看以下链接的最新更新

For Swift Use Below Code

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

Check out latest update on following Link

荒路情人 2024-12-05 17:20:31

触摸背景以关闭键盘

如果您尚未进入 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。我们现在需要更改笔尖视图的底层类。如果您查看笔尖的主窗口,您会看到该视图中有三个图标。第三个称为“视图”,是笔尖的主视图,其中包含所有其他控件和视图作为子视图。
单击名为“视图”的图标,它代表笔尖的容器视图。按␣4调出身份检查器。我们可以在此处更改 Interface Builder 中任何对象实例的基础类。

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

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

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

笔记
保留笔尖,让我们回去尝试一下。再次编译并运行您的应用程序。这次,键盘不仅应该在点击“完成”按钮时消失,而且当您单击非活动控件的任意位置时也应该消失,这是用户所期望的行为。

Touching the Background to Close the Keyboard

Go to Xcode if you’re not already there. We need to add one more action to our controller class. Add the following line to your Control_FunViewController.h file:

#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  

Save the header file; switch over to the implementation file, and add this code, which simply tells both text fields to yield first responder status if they have it. It is perfectly safe to call resignFirstResponder on a control that is not the first responder, so we can safely call it on both text fields without having to check whether either is the first responder.

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

TIP
Save this file, and go back to Interface Builder. We now need to change the underlying class of our nib’s view. If you look at the nib’s main window , you’ll see that there are three icons in that view. The third one, called View, is our nib’s main view that holds all the other controls and views as subviews.
Single-click the icon called View, which represents our nib’s container view. Press ␣4 to bring up the identity inspector. This is where we can change the underlying class of any object instance in Interface Builder.

You’ll be switching between header and implementation files a lot as you code. Fortunately, Xcode has a key combination that will switch you between these files quickly. The default key combination is ␣␣␣ (option-command-up arrow), although you can change it to anything you want using Xcode’s preferences.76

The field labeled Class currently says UIView. Change it to read UIControl. All controls that are capable of trig- gering action methods are subclasses of UIControl, so by changing the underlying class, we have just given this view the ability to trigger action methods. You can verify this by pressing ␣2 to bring up the connections inspector.

Drag from the Touch Down event to the File’s Owner icon, and choose the backgroundTap: action. Now, touches anywhere in the view without an active control will trigger our new action method, which will cause the keyboard to retract.

NOTE
Save the nib, and let’s go back and try it. Compile and run your application again. This time, the keyboard should disappear not only when the Done button is tapped but also when you click anywhere that’s not an active control, which is the behavior that your user will expect.

逐鹿 2024-12-05 17:20:31

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

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

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

我意识到这不是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;

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

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

I tried implementing some of the solutions here and found that there were some issues with them. Notably, My UIView contains a UIScrollView, which appears to intercept touches.

When that failed, I considered that "tapping anywhere" is a little bit of an unspecified behavior, requiring the user to guess how to dismiss the keyboard instead of giving them clear guidance.

Also, I have a "Return" or "Done" button on every other keyboard I show in the app, so I was determined to give the user an easy, intuitive, clearly-specified way to dismiss the keyboard with a Number Pad that was in line with the other keyboard dismissal mechanisms in use.

I realize that this isn't what the OP is specifically requesting, but I believe it to be a better solution than the "tap anywhere" request (and it's easy to implement!).

The following code is called as part of -viewDidLoad in my UIViewController.

// 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;

With that, there's a nice, pretty, intuitive control added to the top of the keyboard that clearly indicates how the user should proceed when they are finished with their text entry.

I still believe Apple should provide a "Done" button for this keyboard (like the link posted by Janak Nirmal), but this is the most elegant non-Apple solution to me.

江心雾 2024-12-05 17:20:31

您可以通过在插座上放置一个 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 中 它最终看起来像这样:

在此处输入图像描述

You can implement @mbm's answer really nicely by putting a didSet on the outlet and attaching your inputAccessoryView there:

Swift code:

  @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
  }}

In xcode 8 / iOS 10 It ends up looking something like this:

enter image description here

梦罢 2024-12-05 17:20:31

您必须使用 UITapGestureRecognizer 来实现此目的。

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

然后在您的missNumberKeyboard 方法中,

-(Void)dismissNumberKeyboard : (id)sender {

   [yourTextField resignFirstResponder];

}

快乐编码!

You must use UITapGestureRecognizer to achieve this.

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

Then in your dismissNumberKeyboard method,

-(Void)dismissNumberKeyboard : (id)sender {

   [yourTextField resignFirstResponder];

}

Happy coding!

音栖息无 2024-12-05 17:20:31

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

  1. View Controller is subclass for UITextFieldDelegate
  2. 在 vi​​ewDidLoad 函数中,您必须设置 yourPhonePadField.delegate = self
  3. 并重写此函数:

    覆盖 func TouchesBegan(_ Touches: Set, with event: UIEvent?) {
       self.view.endEditing(true) 
    }
    

For swift 3/4 I like this case:

  1. View Controller is subclass for UITextFieldDelegate
  2. In the viewDidLoad function, you have to set yourPhonePadField.delegate = self
  3. And override this function:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
       self.view.endEditing(true) 
    }
    
谁把谁当真 2024-12-05 17:20:31

只需创建一个像这样的简单函数..

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

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

Just make a simple function like this one..

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

now go to ur nib file and connect this function with the textfield with didEndOnExit and you are good to go. Now when u will click outside ur textfield the keyboard will hide itself.

爱已欠费 2024-12-05 17:20:31

通常,当用户触摸“取消”按钮时,我用它来关闭键盘 -

- (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];
}

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

Normally, when the user touches on 'Cancel' button, I use this to dismiss Keyboard -

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

If you want to do this for when the user touches anywhere outside the keyboard area, then you need to implement touchesEnded & put this code there -

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

I myself have not tried this, but I recon this should do the trick...

維他命╮ 2024-12-05 17:20:31

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

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。如果您喜欢,请将其标记为答案。

-阿克谢

I had to implement a similar UX for my UITableView (inside which appears a UITextField). First, add a UITapGestureRecognizer to the tableView. This will begin to catch all the taps that occur from now on.

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

The side-effect is however, that you do not want to dismiss the keyboard when the user taps on the UITextField itself. So, this case has to be distinguished.

The handleTap method implementation looks something like-

/*
 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. Mark it as the answer if you like it.

-Akshay

昵称有卵用 2024-12-05 17:20:31

如果您制作了自定义数字键盘或其他弹出窗口,另一种解决方案是在 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];
}

If you've made a custom number pad or other popover, another solution would be to use a gesture recognizer in the init of your UIView like this:

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;

And have the handleSingleTap dismiss the popover if visible and dismiss editing:

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

    [self endEditing:YES];
}
尽揽少女心 2024-12-05 17:20:31

在 xcode 5 中使用点击手势识别器并在 .h 中声明并使用操作选择一个名称并在 .m 中声明

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

In xcode 5 Use a Tap Gesture Recognizer and declare in the .h with action chose a name and in .m

- (IBAction)backgroundTap:(id)sender {
    [self.view endEditing: YES];
}
最丧也最甜 2024-12-05 17:20:31

这里有很多答案,但仍然需要努力使用 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 实现代码中,并通过控制单击并将其拖动到实现代码将其与点击手势识别器关联。

为我工作。

Lots of answers here but still had to struggle to figure it out using XCode 5.
Read this:
https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizer_basics/GestureRecognizer_basics.html

Add a Tap Gesture Recognizer to your UIScrollView. Set its delegate to be the viewcontroller.

Add this method:

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

to your UIScrollView implementation code and associate it to the Tap Gesture Recognizer by control click and dragging to the implementation code.

Worked for me.

淡莣 2024-12-05 17:20:31

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

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

For Swift, the easiest for dismissing keypad for all text fields by tapping anywhere outside the text field is:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
    self.view.endEditing(true)
}
匿名的好友 2024-12-05 17:20:31

斯威夫特5

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

Swift 5

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
           self.view.endEditing(true)
           return true
 }
却一份温柔 2024-12-05 17:20:30

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

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

就可以了。

Declaring the text field as instance variable or property if it isn't already and implementing a simple method like this:

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

will do just fine.

怀念你的温柔 2024-12-05 17:20:30

尝试这个方法,

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

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

Try this method,

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

Now tap anywhere and see keyboard will dismiss. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文