我想知道如何使键盘消失时,用户触摸以外的UITextField。


当前回答

我拼凑了几个答案。

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

UIGestureRecognizer *tapper;

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

删除当前正在编辑的内容:

- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
    [self.view endEditing:YES];
}

其他回答

在这种情况下,可以使用ScrollView,并添加到文本字段在ScrollView和我想点击ScrollView和视图,然后解散键盘。为了以防万一,我尝试创建了示例代码。像这样,

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
        view.addGestureRecognizer(tapGesture)
        // Do any additional setup after loading the view, typically from a nib.
    }
    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

你的故事板看,就像。

这里有很多关于使用UITapGestureRecognizer的很好的答案——所有这些都打破了UITextField的clear (X)按钮。解决方案是通过它的委托来抑制手势识别器:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
    BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
    return !(touchViewIsButton && touchSuperviewIsTextField);
}

这不是最可靠的解决方案,但对我来说很管用。

所以我只需要解决这个问题,之前的答案都不适用。我的情况是:一个UISearchBar,加上屏幕上的一些其他控件。我想在搜索栏之外点击键盘,但不传播到任何其他控件。当键盘被隐藏时,我希望所有的控制都能工作。

我做了什么:

1)在我的视图控制器中实现一个自定义触摸处理程序。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    if searchBar.isFirstResponder()
    {
        // This causes the first responder, whoever it is, to resign first responder, and hide the keyboard.
        // We also "eat" the touch here and not allow it to propagate further.
        view.endEditing(true)
    }
    else
    {
        // OK to propagate the touch
        super.touchesBegan(touches, withEvent: event)
    }
}

2)添加了一对委托方法(我的是UISearchBar,但也有类似的UITextField)。下面代码中的controlContainerView是一个UIView,里面有一堆按钮。记住,在父视图上设置userInteractionEnabled会禁用它的所有子视图。

 func searchBarTextDidBeginEditing(searchBar: UISearchBar)
 {
     controlContainerView.userInteractionEnabled = false
     someButton.userInteractionEnabled = false
 }

 func searchBarTextDidEndEditing(searchBar: UISearchBar)
 {
     searchBar.resignFirstResponder()

    // Done editing: enable the other controls again.

    controlContainerView.userInteractionEnabled = false
    someButton.userInteractionEnabled = false
}

这个怎么样:我知道这是一个老帖子。它可能会帮助某些人:)

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

斯威夫特4 oneliner

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))