如何在Swift中使键盘在点击搜索栏外部时消失?

64

我试图制作一个Swift的搜索栏,但是当我点击搜索栏以外的区域时无法使键盘消失。当我使用textfield尝试时,这段代码可以完美地解决问题。

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

当我点击文本框外部,键盘就会消失。我想让我的搜索栏也能像文本框一样,以同样的方式工作,因为使用搜索栏并按照同样的方式操作时,它根本不起作用。任何参考资料或代码都对我非常有用。


你可以在下面的链接中找到答案: https://dev59.com/-GAf5IYBdhLWcg3wMwXX - YongUn Choi
我已经尝试过了,所以我得到了我的文本字段的代码,并且它完美地工作,就像我说的那样。但是当我使用搜索栏时,我遇到了一些问题,因为我无法在触摸搜索栏之外的其他区域时使键盘消失。 - aji
11个回答

89

试一下这个:

self.mySearchController.searchBar.endEditing(true)

用你创建的控制器名称替换mySearchController... 如果你不是通过编程方式创建它,而是只从库中拖动了一个搜索栏,那么将它的IBOutlet连接到你的类,并引用它:

用你创建的控制器名称替换mySearchController... 如果你不是通过编程方式创建它,而是只从库中拖动了一个搜索栏,那么将它的IBOutlet连接到你的类,并引用它:

self.mySearchBar.endEditing(true)

你能给我一些线索,如何在搜索栏外部获取点击事件吗?因为当我使用文本字段时,我使用像之前写的那样的函数,它会自动工作以获取当我单击文本字段外部时的事件。你能帮我在搜索栏中拥有类似的功能吗? - aji
你是从库中拖动到你的Storyboard中还是在类的内部创建的? - Koray Birand
我认为你的解决方案很好。但是我想知道当我点击搜索栏之外的区域时会触发哪个事件。如果我知道了这个事件,那么我就可以在其中采取你的建议,这样应该就能正常工作了。 - aji
5
我假设您正在搜索栏下使用表视图或集合视图。它们都有“隐藏键盘”复选框,您可以使用它们。 - Koray Birand
你试过把我的代码行放到你的touchesBegan函数里吗?那应该可以解决问题。 - Koray Birand
显示剩余5条评论

43

如果您正在使用表视图,我发现使用表视图进行消除更加简单易懂。

Swift 4:

self.tableView.keyboardDismissMode = .onDrag

8
我之前完全不知道这个存在,谢谢你分享,Dominic。它真的很好用,而且通过搜索按钮重新设置键盘也是一个不错的附加功能。 - Joshua Hart
2
这应该是被接受的答案。顺便说一下,iPhone上的联系人应用程序似乎正好使用了这种模式。 - Leo

33

测试过且工作正常!

func searchBarSearchButtonClicked(searchBar: UISearchBar) 
{
    searchActive = false;
    self.mySearchBar.endEditing(true)
}

针对 Swift 4.2 进行编辑

func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
    {
        searchActive = false
        self.searchBar.endEditing(true)
    }

1
为什么忽略searchBar参数? - HangarRash

11
 func searchBarSearchButtonClicked(searchBar: UISearchBar) {

        searchActive = false;
        searchProject.resignFirstResponder()
    }

当用户点击键盘上的搜索按钮时,将调用此方法。因此,我们可以隐藏键盘。我认为这是正确的方法。


10

首先,苹果的UISearchBarDelegate是隐藏键盘的正确解决方案,当用户单击搜索按钮且UISearchBar的实例是first responder(了解UIResponder)时。简而言之,searchBarSearchButtonClicked(_:)是您需要完成此任务的方法。

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    searchBar.resignFirstResponder() // hides the keyboard.
    doThingsForSearching()
}
如果它不起作用,请检查您的控制器是否符合UISearchBarDelegate,其次,UISearchBarDelegate是否知道您的类实现(如果您不太明白我在说什么,您应该从这里开始学习委托模式):
class YourAwesomeViewController: UIViewController, UISearchBarDelegate { // pay attention here

    @IBOutlet weak var yourSearchBar: UISearchBar!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.yourSearchBar.delegate = self // and it's important too
    }
}

此外,如果您需要在不触摸搜索按钮的情况下隐藏键盘(用户可能改变搜索内容),使用UITapGestureRecognizer也是一种简单的处理方式。

  1. Ctrl-dragObject Library中将Tap Gesture Recognizer拖动到您的视图控制器中。

enter image description here

  1. Ctrl-drag从故事板中的document outline将最近添加的Tap Gesture Recognizer拖动到您的类实现中作为IBAction

enter image description here

  1. 最后,编写代码:

@IBAction func tapToHideKeyboard(_ sender: UITapGestureRecognizer) { self.yourSearchBar.resignFirstResponder() }

还要别忘了创建 @IBOutlet 以便在类实现中访问搜索栏。

以上两种变体在我的项目中都能很好地工作。


8

Swift 4+:

您可以尝试创建一个轻拍手势,并将其添加到self.view中。

let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(sender:)))
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.isEnabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
self.view.addGestureRecognizer(singleTapGestureRecognizer)

在选择器函数中,您需要调用self.searchBar.resignFirstResponder
@objc func singleTap(sender: UITapGestureRecognizer) {
    self.searchBar.resignFirstResponder()
}

5
class MaCaveViewController: UIViewController, UISearchBarDelegate {
    
    @IBOutlet weak var searchBar: UISearchBar!

    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.delegate = self
    }

    // When button "Search" pressed
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
        print("end searching --> Close Keyboard")
        self.searchBar.endEditing(true)
    }
}

这对我来说非常有效。

这个答案是我第一次就成功的唯一答案。(使用Swift 5)。谢谢! - David_2877

5

您可以使用通用的UIViewController扩展

  1. 只需在项目中添加一个新的Swift文件,并粘贴以下代码片段

代码

extension UIViewController {

    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard(_:)))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard(_ sender: UITapGestureRecognizer) {
        view.endEditing(true)

        if let nav = self.navigationController {
            nav.view.endEditing(true)
        }
    }
 }
  1. 现在从需要键盘隐藏功能的地方,在viewDidLoad方法中调用hideKeyboardWhenTappedAround()函数。

1
我们可以用以下方法来做到这一点。
    func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
        searchBar.showsCancelButton = true;
    }

    func searchBarTextDidEndEditing(searchBar: UISearchBar) {
        searchBar.showsCancelButton = false;
    }

0

这对我在Swift 4中有效。

   func searchBarSearchButtonClicked(_ searchBar: UISearchBar){

    self.searchBar.endEditing(true)

    }

1
为什么要使用 "self" -- 活动的 searchBar 对象被传递到该委托方法中。"searchBar.endEditing(true)" 可以正常工作。使用 self,您正在引用外部声明(可能与当前实例不同)。 - mobibob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接