iOS - 在UITextField外部触摸时关闭键盘

jon*_*atr 451 cocoa-touch uitextfield uikit ios

我想知道如何在用户触摸外面时使键盘消失UITextField.

Jen*_*n2k 748

您需要添加一个UITapGestureRecogniser并将其分配给视图,然后UITextField在其选择器上调用resign first responder .

代码:

在viewDidLoad中

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];

[self.view addGestureRecognizer:tap];
Run Code Online (Sandbox Code Playgroud)

在dismissKeyboard中:

-(void)dismissKeyboard 
{
    [aTextField resignFirstResponder];
}
Run Code Online (Sandbox Code Playgroud)

(aTextField负责键盘的文本字段在哪里)

Swift 3版看起来像那样

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
Run Code Online (Sandbox Code Playgroud)

对于dismissKeyboard

func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    aTextField.resignFirstResponder()
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为比`[aTextField resignFirstResponder]`更好``[self.view endEditing:YES];`它不需要对文本字段的引用,并且适用于多个文本字段 (133认同)
  • 所以不必定义的任何方法,一个班轮将是:`[self.view addGestureRecognizer:[[UITapGestureRecognizer的alloc] initWithTarget:self.view动作:@selector(endEditing :)]];` (89认同)
  • @ParthBhatt我添加了`[tap setCancelsTouchesInView:NO];`@@qiaoyi的答案; 我遇到了一个没有响应行选择的表的问题.5年后,我希望这有助于其他人. (6认同)
  • 这样做但它的作用是它还禁用或使导航栏按钮不可点击.那么有解决方法吗? (5认同)
  • 当用户执行滚动等其他手势时,这不起作用.更好的解决方案是使用hitTest:withEvent: (4认同)
  • 如果您需要触摸文本字段右侧的"X"图标来清理字段,这样做并不好.如果启用手势识别器,则需要在焦点位于textField上时保持启用,因此您无法触摸此类"X"图标. (4认同)
  • Swift单行:`self.view.addGestureRecognizer(UITapGestureRecognizer(target:self.view,action:#selector(UIView.endEditing(_ :)))) (4认同)
  • 需要添加:` - (void)textFieldDidBeginEditing:(UITextField*)textField {textFieldToResign = textField; 这将有助于重新签名所选的textField (2认同)

dre*_*ish 174

我捣乱了几个答案.

使用在期间初始化的ivar viewDidLoad:

UIGestureRecognizer *tapper;

- (void)viewDidLoad
{
    [super viewDidLoad];
    tapper = [[UITapGestureRecognizer alloc]
                initWithTarget:self action:@selector(handleSingleTap:)];
    tapper.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapper];
}
Run Code Online (Sandbox Code Playgroud)

取消当前正在编辑的内容:

- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
    [self.view endEditing:YES];
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您未在此处添加cancelsTouchesInView = false,则您将无法在视图中选择其他类型的项目.您的点击将被gestureRecognizer拦截. (2认同)

Pra*_*ysa 102

检查一下,这将是最简单的方法,

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
      [self.view endEditing:YES];// this will do the trick
}
Run Code Online (Sandbox Code Playgroud)

要么

该库将处理包括滚动条自动滚动,点击空间以隐藏键盘等...

https://github.com/michaeltyson/TPKeyboardAvoiding

  • 当用户触摸视图上的其他控件时,它不会隐藏键盘.例如:我在UIView上有一个UIButton和UITextField.我点击UITextField,然后点击按钮,在这种情况下键盘不会隐藏. (3认同)
  • @JacobDam你是对的.目标是resignfirstresponder隐藏键盘,如果*任何*发生在aTextField之外. (2认同)

Qia*_* Yi 87

我看到有些人在使用这种UITapGestureRecognizer方法时遇到了问题.我完成此功能的最简单方法是在保持现有按钮的点击行为不变的情况下,只添加一行@ Jensen2k的答案:

[tap setCancelsTouchesInView:NO];
Run Code Online (Sandbox Code Playgroud)

这允许我现有的按钮仍然可以工作而不使用@Dmitry Sitnikov的方法.

property在这里阅读(搜索CancelsTouchesInView):UIGestureRecognizer类参考

我不确定它如何与滚动条一起使用,因为我看到有些问题,但希望其他人可能遇到我所拥有的相同情况.

  • 我还想补充一点,对于那些使用`UIImageView`在视图背面有背景图像的人,添加`[imageView setUserInteractionEnabled:NO];`并"点击"它,这使得这个方法有效. (3认同)

Dmi*_*kov 55

最好创建UIView一个UIControl(在接口构建器中)的实例,然后将它们的TouchUpInside事件连接到dismissKeyboard方法.此IBAction方法如下所示:

- (IBAction)dismissKeyboard:(id)sender {
    [aTextBox resignFirstResponder];
}
Run Code Online (Sandbox Code Playgroud)

  • 你不应该让UIView成为UIControl.确保UIView已启用用户交互. (4认同)

Rob*_*Rob 28

Swift版本,它与其他元素(如一个UIButton或另一个UITextField)组合使用:

override func viewDidLoad() {
    super.viewDidLoad()

    let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
    tapper.cancelsTouchesInView = false
    view.addGestureRecognizer(tapper)
}
Run Code Online (Sandbox Code Playgroud)


FBe*_*nte 24

斯威夫特4

设置你的UIViewController这种扩展方法一旦例如在viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    self.setupHideKeyboardOnTap()
}
Run Code Online (Sandbox Code Playgroud)

即使敲击键盘,键盘也会被解雇NavigationBar.

import UIKit
extension UIViewController {
    /// Call this once to dismiss open keyboards by tapping anywhere in the view controller
    func setupHideKeyboardOnTap() {
        self.view.addGestureRecognizer(self.endEditingRecognizer())
        self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
    }

    /// Dismisses the keyboard from self.view
    private func endEditingRecognizer() -> UIGestureRecognizer {
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
        tap.cancelsTouchesInView = false
        return tap
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止最好的答案是有效的.谢谢. (4认同)
  • 兄弟,你钉了!这个答案是完美的,并且效果非常好,非常感谢。 (2认同)

Mr *_*r H 17

怎么样:我知道这是一个老帖子.它可能有助于某人:)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
    NSArray *subviews = [self.view subviews];
    for (id objects in subviews) {
        if ([objects isKindOfClass:[UITextField class]]) {
            UITextField *theTextField = objects;
            if ([objects isFirstResponder]) {
                [theTextField resignFirstResponder];
            }
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)


edu*_*udi 15

这是一个很好的通用解决方案:

Objective-C的:

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

迅速:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    self.view.endEditing(true)
}
Run Code Online (Sandbox Code Playgroud)

基于@icodebuster解决方案:https://stackoverflow.com/a/18756253/417652


new*_*per 11

斯威夫特4 oneliner

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
Run Code Online (Sandbox Code Playgroud)


Enz*_*ran 10

我认为最简单(也是最好)的方法是子类化全局视图并使用hitTest:withEvent方法来监听任何触摸.没有注册键盘上的触摸,所以只有在触摸/滚动/滑动/捏合...其他地方,然后调用时,才会调用hitTest:withEvent [self endEditing:YES].

这比使用更好,touchesBegan因为touchesBegan如果单击视图顶部的按钮则不会调用.例如,它比UITapGestureRecognizer无法识别滚动手势更好.它也比使用昏暗的屏幕更好,因为在复杂和动态的用户界面中,你无法在任何地方放置昏暗的屏幕.此外,它不会阻止其他操作,您不需要点击两次以选择外部按钮(例如a UIPopover).

此外,它比调用更好[textField resignFirstResponder],因为屏幕上可能有许多文本字段,因此这适用于所有这些字段.


Kor*_*ker 8

这必须是通过触摸外部隐藏键盘的最简单方法:

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

(当用户点击文本字段外的其他区域时,如何关闭键盘?)


Chr*_*row 6

您可以使用XCode 6及更高版本中的Storyboard执行此操作:


创建隐藏键盘的操作

将其添加到ViewController使用的类的头文件中:

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end
Run Code Online (Sandbox Code Playgroud)

然后将其添加到同一ViewController的实现文件中:

- (IBAction)dissmissKeyboardOnTap:(id)sender{
    [[self view]endEditing:YES];
}
Run Code Online (Sandbox Code Playgroud)

这将是您的故事板场景(即ViewController)的"已接收操作"之一:

在此输入图像描述


将操作连接到用户事件

现在,您需要将此操作连接到触摸键盘的用户手势.

重要 - 您需要将故事板中包含的'UIView'转换为UIControl,以便它可以接收事件.从View Controller Scene层次结构中选择视图:

在此输入图像描述

...并改变它的类:

在此输入图像描述

现在从场景的"已接收动作"旁边的小圆圈拖动到场景的"空"部分(实际上是将"已接收的动作"拖动到UIControl).您将看到一系列可以将您的操作连接到的事件:

在此输入图像描述

选择"内部修饰"选项.您现在已将您创建的IBAction挂钩到用户触摸键盘的操作.当用户轻敲键盘时,它现在将被隐藏.

(注意:要将操作挂钩到事件,您还可以将接收到的操作直接拖到View Controllers层次结构中的UIControl上.它在层次结构中显示为"Control".)


rpt*_*thi 5

如果我找到了你,你想要在键盘外面点击,textfield但你没有参考你的textfield.

试试这个;

  • 拿全局textField,让我们调用它 reftextField
  • 现在在textFieldDidBeginEditingset引用的文本字段中

    - (void) textFieldDidBeginEditing:(UITextField *)textField{
        reftextField = textField;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在您可以愉快地使用任何按钮时钟,(在开始编辑时添加透明按钮推荐)

    - (void)dismissKeyboard {
          [reftextField resignFirstResponder];
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者对于辞职完成按钮试试这个.

    //for resigning on done button    
    - (BOOL) textFieldShouldReturn:(UITextField *)textField{
        [textField resignFirstResponder];
        return YES;
    }
    
    Run Code Online (Sandbox Code Playgroud)


Joe*_*tti 5

如果视图完全嵌入在a中,UIScrollView则可以使用以下命令:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Run Code Online (Sandbox Code Playgroud)

前者将在滚动表格视图时将键盘设置为关闭屏幕,后者将像股票消息应用程序一样隐藏键盘.

请注意,这些可在iOS 7.0或更高版本上使用.


Moh*_*sir 5

在 swift 5 中,您可以使用以下代码来关闭文本字段之外的键盘

override func viewDidLoad() {
    // ... code

    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard(_:)))
    self.view.addGestureRecognizer(tapGesture)  
}

@objc func dismissKeyboard(_ sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}
Run Code Online (Sandbox Code Playgroud)