62

I try to make my searchbar on swift, but I have a problem to dismiss keyboard on screen when I pressed out of searchbar. When I try with textfield, it works perfectly fine with this code.

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

It work when i press out of my textfield and then the keyboard is gone. I want to make like that with my searchbar, because when I use searchbar and use the same way like textfield, it doesn't work at all. Any reference or code is very useful for me.

peterh
  • 11,875
  • 18
  • 85
  • 108
aji
  • 651
  • 1
  • 5
  • 10
  • You can find the answer in the link below: http://stackoverflow.com/questions/24908966/hide-keyboard-for-text-field-in-swift-programming-language – YongUn Choi Apr 28 '15 at 16:58
  • i had try that so i get my code for textfield and it works perfectly fine like what i say, but i have some problem when i have to use searchbar, because i can't make my keyboard dismiss when i touch another area outside my searchbar – aji Apr 28 '15 at 17:08

11 Answers11

88

try this :

self.mySearchController.searchBar.endEditing(true)

replace mySearchController with your created controller name.. If you did not create it programmatically but instead you just dragged a search bar from library then IBoutlet your searchable to your class and reference it as:

self.mySearchBar.endEditing(true)
Koray Birand
  • 1,956
  • 17
  • 22
  • could you give me any clue how to get event on click outside my searchbar, because when i use textfield, i use function like what i write before and it works automatically to get event when i click outside my textfield. Can you help me to have function like that in searchbar – aji Apr 28 '15 at 17:47
  • did you drag it from the library to your storyboard or created it from an inside of a class.. ? – Koray Birand Apr 28 '15 at 17:49
  • i dragged it from my storyboard – aji Apr 28 '15 at 17:52
  • I think your solution is fine. But i want to know what event that i get when i click outside my searchbar. If i know that event then i could take your suggestion inside it and it should be working. – aji Apr 28 '15 at 17:55
  • 5
    I assume you are using a tableview or a collection view under the search bar . they both have dismiss keyboard check box. You can use them. – Koray Birand Apr 28 '15 at 17:58
  • did you try putting my line into your touchesBegan func. ? that should do it. – Koray Birand Apr 28 '15 at 18:00
  • yes i put it inside my touchesBegan fun, but i think it just working with textsielddelegate, not with searcbar. – aji Apr 28 '15 at 18:03
  • I created a sample project for you, check it out. http://www.koraybirand.co.uk/download.asp?usr=test&file=/download/xcode/SearchBarTest.zip – Koray Birand Apr 28 '15 at 18:11
  • I think i realize somethink, i should reconnect with every view first because i make another view parent and searchbar as a child, but your solution is work if i use a simple one, thank – aji Apr 28 '15 at 18:41
  • I realize it from this http://stackoverflow.com/questions/7482266/resign-keyboard-when-losing-focus-on-uisearchbar?rq=1 – aji Apr 28 '15 at 18:41
43

I found it easier and simplier to use Table View for dismissal. (If you're using table view)

Swift 4:

self.tableView.keyboardDismissMode = .onDrag
Dominic Smith
  • 632
  • 7
  • 12
  • 8
    I didn't even know this existed, thanks for sharing Dominic, worked like a charm and a nice addition to also resigning the keyboard through the search button. – Joshua Hart Sep 11 '19 at 12:15
  • 2
    This should be the accepted answer. BTW the Contacts app on iPhone seems to use exactly this mode. – Leo Nov 30 '19 at 10:51
33

Tested and working!

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

Edit for Swift 4.2

func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
    {
        searchActive = false
        self.searchBar.endEditing(true)
    }
Community
  • 1
  • 1
Thiago Arreguy
  • 2,739
  • 2
  • 19
  • 18
11
 func searchBarSearchButtonClicked(searchBar: UISearchBar) {

        searchActive = false;
        searchProject.resignFirstResponder()
    }

This method will be invoked when user click search button on keyboard.So here we can dismiss keyboard.I think this is the right method.

10

Firstly, Apple's UISearchBarDelegate is the correct solution to hide keyboard when users click a search button while UISearchBar's instance is the first responder (learn UIResponder). In short, searchBarSearchButtonClicked(_:) is what you need for this task.

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    searchBar.resignFirstResponder() // hides the keyboard.
    doThingsForSearching()
}

If it doesn't work, check, does your controller conform to UISearchBarDelegate and secondly, does UISearchBarDelegate know about your class implementation (if you don't quite understand what am I talking about, you should learn delegation pattern starting to read here):

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

Further, if you need to hide the keyboard touching outside of search bar without touching the search button (the user may change his mind to search something), UITapGestureRecognizer is a simple way too to deal with that.

  1. Ctrl-drag a Tap Gesture Recognizer from the Object Library to your View Controller.

enter image description here

  1. Ctrl-drag the recently added Tap Gesture Recognizer from the document outline in the storyboard to your class implementation as IBAction.

enter image description here

  1. Finally, write a code:

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

Also, don't forget to create @IBOutlet for the search bar to have an access inside your class implementation.

Both variants above work well in my project.

devshok
  • 737
  • 1
  • 8
  • 19
8

Swift 4+:

You can try, creating a tap gesture and add in the 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)

and in selector func you call self.searchBar.resignFirstResponder

@objc func singleTap(sender: UITapGestureRecognizer) {
    self.searchBar.resignFirstResponder()
}
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
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)
    }
}

This works very well for me.

atereshkov
  • 4,311
  • 1
  • 38
  • 49
XenoX
  • 409
  • 6
  • 14
5

You can use a general UIViewController extension

  1. Just add a new swift file on the project and paste the following code snippet

Code

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. Now call hideKeyboardWhenTappedAround() from viewDidLoad method where you want keyboard hiding feature.
dip
  • 3,548
  • 3
  • 24
  • 36
1

we can do this with following methods

    func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
        searchBar.showsCancelButton = true;
    }

    func searchBarTextDidEndEditing(searchBar: UISearchBar) {
        searchBar.showsCancelButton = false;
    }
anjnkmr
  • 838
  • 15
  • 37
0

This works for me in Swift 4

   func searchBarSearchButtonClicked(_ searchBar: UISearchBar){

    self.searchBar.endEditing(true)

    }
nanospeck
  • 3,388
  • 3
  • 36
  • 45
  • 1
    why are you using "self" -- the searchBar object that is active is being passed into this delegate's method. "searchBar.endEditing(true)" works just fine. with self, you are referencing your outer declaration (which may or may NOT be the same instance). – mobibob Jan 02 '20 at 00:29
0

it is more recomended than searchBar.endEditing(true) self.mySearchController.searchBar.resignFirstResponder()

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 18 '23 at 21:26