Cierre el teclado de iOS tocando en cualquier lugar con Swift

He estado buscando todo esto, pero parece que no puedo encontrarlo. Sé cómo descartar el teclado con Objective-C pero no tengo idea de cómo hacerlo con Swift . ¿Alguien sabe?

 override func viewDidLoad() { super.viewDidLoad() //Looks for single or multiple taps. let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard") //Uncomment the line below if you want the tap not not interfere and cancel other interactions. //tap.cancelsTouchesInView = false view.addGestureRecognizer(tap) } //Calls this function when the tap is recognized. func dismissKeyboard() { //Causes the view (or one of its embedded text fields) to resign the first responder status. view.endEditing(true) } 

Aquí hay otra forma de realizar esta tarea si va a utilizar esta funcionalidad en múltiples UIViewControllers :

 // Put this piece of code anywhere you like extension UIViewController { func hideKeyboardWhenTappedAround() { let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard)) tap.cancelsTouchesInView = false view.addGestureRecognizer(tap) } @objc func dismissKeyboard() { view.endEditing(true) } } 

Ahora en cada UIViewController , todo lo que tienes que hacer es llamar a esta función:

 override func viewDidLoad() { super.viewDidLoad() self.hideKeyboardWhenTappedAround() } 

Esta función se incluye como una función estándar en mi repository que contiene muchas extensiones útiles de Swift como esta, compruébalo: https://github.com/goktugyil/EZSwiftExtensions

Una respuesta a su pregunta sobre cómo descartar el teclado en Xcode 6.1 usando Swift a continuación:

 import UIKit class ItemViewController: UIViewController, UITextFieldDelegate { @IBOutlet var textFieldItemName: UITextField! @IBOutlet var textFieldQt: UITextField! @IBOutlet var textFieldMoreInfo: UITextField! override func viewDidLoad() { super.viewDidLoad() textFieldItemName.delegate = self textFieldQt.delegate = self textFieldMoreInfo.delegate = self } ... /** * Called when 'return' key pressed. return NO to ignore. */ func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } /** * Called when the user click on the view (outside the UITextField). */ override func touchesBegan(touches: Set, withEvent event: UIEvent?) { self.view.endEditing(true) } } 

( Fuente de esta información ).

Puedes llamar

 resignFirstResponder() 

en cualquier instancia de un UIResponder, como un UITextField. Si lo llama en la vista que actualmente está causando que se muestre el teclado, el teclado se cerrará.

 //Simple exercise to demonstrate, assuming the view controller has a //Textfield, Button and a Label. And that the label should display the //userinputs when button clicked. And if you want the keyboard to disappear //when clicken anywhere on the screen + upon clicking Return key in the //keyboard. Dont forget to add "UITextFieldDelegate" and //"self.userInput.delegate = self" as below import UIKit class ViewController: UIViewController,UITextFieldDelegate { @IBOutlet weak var userInput: UITextField! @IBAction func transferBtn(sender: AnyObject) { display.text = userInput.text } @IBOutlet weak var display: UILabel! override func viewDidLoad() { super.viewDidLoad() //This is important for the textFieldShouldReturn function, conforming to textfieldDelegate and setting it to self self.userInput.delegate = self } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //This is for the keyboard to GO AWAYY !! when user clicks anywhere on the view override func touchesBegan(touches: Set, withEvent event: UIEvent?) { self.view.endEditing(true) } //This is for the keyboard to GO AWAYY !! when user clicks "Return" key on the keyboard func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } } 

para Swift 3 es muy simple

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

si desea ocultar el teclado al presionar la tecla RETORNO

 func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true } 

pero en el segundo caso, también necesitará pasar el delegado de todos los campos de texto a ViewController en Main.Storyboard

Swift 3: la forma más fácil de cerrar el teclado:

  //Dismiss keyboard method func keyboardDismiss() { textField.resignFirstResponder() } //ADD Gesture Recignizer to Dismiss keyboard then view tapped @IBAction func viewTapped(_ sender: AnyObject) { keyboardDismiss() } //Dismiss keyboard using Return Key (Done) Button //Do not forgot to add protocol UITextFieldDelegate func textFieldShouldReturn(_ textField: UITextField) -> Bool { keyboardDismiss() return true } 

La respuesta de Dash es correcta y preferida. Un enfoque más de “tierra quemada” es llamar a view.endEditing(true) . Esto provoca que view y todas sus subvistas resignFirstResponder . Si no tiene una referencia a la vista que le gustaría descartar, esta es una solución estrafalaria pero efectiva.

Tenga en cuenta que, personalmente, creo que debería tener una referencia a la vista en la que desea renunciar a la primera respuesta. .endEditing(force: Bool) es un enfoque bárbaro; por favor no lo uses.

En el guión gráfico:

  1. selecciona TableView
  2. desde el lado derecho, seleccione el inspector de atributos
  3. en la sección del teclado: selecciona el modo de desactivación que deseas

Swift 3:

Extensión con Selector como parámetro para poder hacer cosas adicionales en la función de descarte y cancelsTouchesInView para evitar distorsiones con toques en otros elementos de la vista.

 extension UIViewController { func hideKeyboardOnTap(_ selector: Selector) { let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: selector) tap.cancelsTouchesInView = false view.addGestureRecognizer(tap) } } 

Uso:

 override func viewDidLoad() { super.viewDidLoad() self.hideKeyboardOnTap(#selector(self.dismissKeyboard)) } func dismissKeyboard() { view.endEditing(true) // do aditional stuff } 

! [cómo desactivar el teclado …] [1]

 import UIKit class ViewController: UIViewController,UITextFieldDelegate { @IBOutlet weak var username: UITextField! @IBOutlet weak var password: UITextField! override func viewDidLoad() { super.viewDidLoad() username.delegate = self password.delegate = self // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore. { textField.resignFirstResponder() return true; } override func touchesBegan(_: Set, with: UIEvent?) { username.resignFirstResponder() password.resignFirstResponder() self.view.endEditing(true) } } 

Swift 4 trabajando

Cree la extensión como se hideKeyboardWhenTappedAround() continuación y llame a hideKeyboardWhenTappedAround() en su controlador de vista base.

 // // UIViewController+Extension.swift // Project Name // // Created by ABC on 2/3/18. // Copyright © 2018 ABC. All rights reserved. // import UIKit extension UIViewController { func hideKeyboardWhenTappedAround() { let tapGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard)) view.addGestureRecognizer(tapGesture) } @objc func hideKeyboard() { view.endEditing(true) } } 

Si usa una vista de desplazamiento, podría ser mucho más simple.

Solo seleccione Dismiss interactively en el guión gráfico.

  import UIKit class ItemViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var nameTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() self.nameTextField.delegate = self } // Called when 'return' key pressed. return NO to ignore. func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } // Called when the user click on the view (outside the UITextField). override func touchesBegan(touches: Set, withEvent event: UIEvent?) { self.view.endEditing(true) } } 

Este trazador de líneas renuncia al teclado de todos (cualquiera) el UITextField en un UIView

 self.view.endEditing(true) 

Encontré la mejor solución incluida la respuesta aceptada de @Esqarrouth, con algunos ajustes:

 extension UIViewController { func hideKeyboardWhenTappedAround() { let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboardView") tap.cancelsTouchesInView = false view.addGestureRecognizer(tap) } func dismissKeyboardView() { view.endEditing(true) } } 

La línea tap.cancelsTouchesInView = false fue crítica: asegura que el UITapGestureRecognizer no impide que otros elementos en la vista reciban la interacción del usuario.

El método dismissKeyboard() se cambió a un dismissKeyboardView() ligeramente menos elegante. Esto se debe a que en la base de código bastante antigua de mi proyecto, hubo numerosas ocasiones en las que dismissKeyboard() ya se usaba (supongo que esto no es raro), lo que causa problemas con el comstackdor.

Entonces, como se indicó anteriormente, este comportamiento se puede habilitar en controladores de vista individuales:

 override func viewDidLoad() { super.viewDidLoad() self.hideKeyboardWhenTappedAround() } 

Como progtwigdor principiante puede ser confuso cuando las personas producen respuestas más hábiles e innecesarias … ¡No tiene que hacer ninguna de las cosas complicadas que se muestran arriba! …

Aquí está la opción más simple … En el caso de que su teclado aparezca en respuesta al campo de texto – Dentro de la función de pantalla táctil solo agregue la función resignFirstResponder . Como se muestra a continuación, el teclado se cerrará porque se libera el Primer Respondedor (saliendo de la cadena Responder) …

 override func touchesBegan(_: Set, with: UIEvent?){ MyTextField.resignFirstResponder() } 

Para Swift3

Registre un reconocedor de eventos en viewDidLoad

 let tap = UITapGestureRecognizer(target: self, action: #selector(hideKeyBoard)) 

entonces necesitamos agregar el gesto a la vista en el mismo viewDidLoad.

 self.view.addGestureRecognizer(tap) 

Entonces tenemos que inicializar el método registrado

 func hideKeyBoard(sender: UITapGestureRecognizer? = nil){ view.endEditing(true) } 

Para construir de la respuesta correcta siempre uso la siguiente extensión:

 extension UIApplication { /// Dismiss keyboard from key window. open static func endEditing(_ force: Bool = false) { shared.keyWindow?.endEditing(force) } } 

De esta manera, en caso de que la clase en la que bash cancelar la edición no tenga una propiedad de view o no sea una subclase de UIView , solo puedo llamar a UIApplication.endEditing() .

También puede agregar un reconocedor de gestos de toque para renunciar al teclado. :RE

 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let recognizer = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) backgroundView.addGestureRecognizer(recognizer) } func handleTap(recognizer: UITapGestureRecognizer) { textField.resignFirstResponder() textFieldtwo.resignFirstResponder() textFieldthree.resignFirstResponder() println("tappped") } 

Otra posibilidad es simplemente agregar un botón grande sin contenido que se encuentre debajo de todas las vistas que pueda necesitar tocar. Dale una acción llamada:

 @IBAction func dismissKeyboardButton(sender: AnyObject) { view.endEditing(true) } 

El problema con un reconocedor de gestos fue para mí, que también atrapó todos los toques que quería recibir de tableViewCells.

Si tiene otras vistas que también deberían recibir el toque, debe establecer cancelsTouchesInView = false

Me gusta esto:

 let elsewhereTap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) elsewhereTap.cancelsTouchesInView = false self.view.addGestureRecognizer(elsewhereTap) 

En Swift 4, agregue @objc:

En viewDidLoad:

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

Función:

 @objc func dismissKeyboard() { view.endEditing(true) } 

Agregue esta extensión a su ViewController:

  extension UIViewController { // Ends editing view when touches to view open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) self.view.endEditing(true) } } 

Cuando hay más de un campo de texto en la vista

Para seguir la recomendación de @modelocache de evitar llamar a view.endEditing() , puede realizar un seguimiento del campo de texto que se convirtió en el primero en responder, pero que es desordenado y propenso a errores.

Una alternativa es llamar a resignFirstResponder() en todos los campos de texto en viewcontroller . Aquí hay un ejemplo de cómo crear una colección de todos los campos de texto (que en mi caso era necesaria para el código de validación de todos modos):

 @IBOutlet weak var firstName: UITextField! @IBOutlet weak var lastName: UITextField! @IBOutlet weak var email: UITextField! var allTextFields: Array! // Forced unwrapping so it must be initialized in viewDidLoad override func viewDidLoad() { super.viewDidLoad() self.allTextFields = [self.firstName, self.lastName, self.email] } 

Con la colección disponible, es una simple cuestión de iterar a través de todos ellos:

 private func dismissKeyboard() { for textField in allTextFields { textField.resignFirstResponder() } } 

Entonces ahora puede llamar a dismissKeyboard() en su reconocedor de gestos (o donde sea apropiado para usted). El inconveniente es que debe mantener la lista de UITextField s cuando agrega o elimina campos.

Comentarios bienvenidos. Si hay un problema al llamar a resignFirstResponder() en los controles que no responden primero, o si existe una forma fácil y segura de realizar un seguimiento de la primera respuesta actual, ¡me encantaría saberlo!

Trabajé en uisearchbar. Mira el mio.

 import UIKit class BidderPage: UIViewController,UISearchBarDelegate,UITableViewDataSource { let recognizer = UITapGestureRecognizer() // Set recogniser as public in case of tableview and didselectindexpath. func searchBarTextDidBeginEditing(searchBar: UISearchBar) { recognizer.addTarget(self, action: "handleTap:") view.addGestureRecognizer(recognizer) } func handleTap(recognizer: UITapGestureRecognizer) { biddersearchbar .resignFirstResponder() } func searchBarTextDidEndEditing(searchBar: UISearchBar) { view .removeGestureRecognizer(recognizer) } 

Prefiero este one-liner :

 view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "dismissKeyboardFromView:")) 

Simplemente ponga eso en la función override viewDidLoad en cualquier UIViewController subclasificado que quiera que ocurra, y luego ponga el siguiente código en un nuevo archivo vacío en su proyecto llamado “UIViewController + dismissKeyboard.swift”:

 import UIKit extension UIViewController { // This function is called when the tap is recognized func dismissKeyboardFromView(sender: UITapGestureRecognizer?) { let view = sender?.view view?.endEditing(true) } } 

Te tengo fam

 override func viewDidLoad() { super.viewDidLoad() /*This ensures that our view loaded*/ self.textField.delegate = self /*we select our text field that we want*/ self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: Selector("dismissKeyboard"))) } func dismissKeyboard(){ /*this is a void function*/ textField.resignFirstResponder() /*This will dismiss our keyboard on tap*/ } 

Encontré esta solución simple: 1. Agregue UITapGestureRecognizer a su vista Controlador 2. Agregue IBAction a su UITapGestureRecognizer 3. Finalmente puede renunciar al primer respondedor

 class ViewController: UIViewController { @IBOutlet var tap: UITapGestureRecognizer! @IBOutlet weak var label: UILabel! @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } @IBAction func dismissUsingGesture(_ sender: UITapGestureRecognizer) { self.textField.resignFirstResponder() label.text = textField.text! } } 

Aquí hay una manera sucinta de hacerlo:

 let endEditingTapGesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))) endEditingTapGesture.cancelsTouchesInView = false view.addGestureRecognizer(endEditingTapGesture) 

Swift 3

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