繁体   English   中英

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

[英]How to dismiss number pad keyboard by tapping anywhere

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

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

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

会做的很好。

试试这个方法,

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

现在点击任何地方,然后键盘就会消失。 :-)

对于 Swift 使用下面的代码

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

查看以下链接的最新更新

触摸背景关闭键盘

如果您还没有在那里,请转到 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。 我们现在需要更改笔尖视图的基础类。 如果您查看笔尖的主窗口,您会看到该视图中有三个图标。 第三个叫做 View,是我们 nib 的主视图,它包含所有其他控件和视图作为子视图。 单击名为 View 的图标,它代表我们的 nib 的容器视图。 按␣4 调出身份检查器。 这是我们可以在 Interface Builder 中更改任何对象实例的基础类的地方。

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

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

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

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

我尝试在这里实施一些解决方案,发现它们存在一些问题。 值得注意的是,我的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;

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

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

您可以通过在插座上放置一个didSet并将您的 inputAccessoryView 附加到那里来很好地实现didSet的答案:

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 中,它最终看起来像这样:

在此处输入图片说明

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

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

然后在你的dismissNumberKeyboard 方法中,

-(Void)dismissNumberKeyboard : (id)sender {

   [yourTextField resignFirstResponder];

}

快乐编码!

对于 swift 3/4 我喜欢这个案例:

  1. 视图控制器是 UITextFieldDelegate 的子类
  2. 在 viewDidLoad 函数中,你必须设置yourPhonePadField.delegate = self
  3. 并覆盖此功能:

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

只需做一个像这样的简单功能..

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

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

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

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

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

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

这里有很多答案,但仍然不得不努力使用 XCode 5 来弄清楚。阅读: https : //developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizer_basics/GestureRecognizer_basics.html

将 Tap Gesture Recognizer 添加到您的 UIScrollView。 将其委托设置为视图控制器。

添加此方法:

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

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

为我工作。

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

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

斯威夫特 5

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

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

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

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

我必须为我的 UITableView 实现一个类似的 UX(里面出现一个 UITextField)。 首先,向 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];
    }
}

哈。 如果您喜欢,请将其标记为答案。

-阿克谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM