outside how dismisskeyboard ios swift uitextfield uikeyboard

ios - how - ¿Cómo descartar el teclado al tocar en cualquier lugar fuera de UITextField(en forma rápida)?



ios swift hide keyboard (17)

Estoy trabajando en un proyecto que tiene un UIViewController, en el controlador de vista hay un UIScrollView y un UITextField en la vista de desplazamiento. Me gusta esto: Estoy tratando de descartar el teclado y ocultarlo después de escribir algo de texto en el campo de texto y tocar en cualquier lugar fuera del campo de texto. He intentado el siguiente código:

override func viewDidLoad() { super.viewDidLoad() self.textField.delegate = self; } override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.view.endEditing(true) }

Funciona para mí cuando toco fuera de la vista de desplazamiento, pero cuando toco en la vista de desplazamiento no pasa nada y el teclado no se oculta.

¿Hay alguna forma de descartar el teclado al tocar en cualquier lugar fuera del campo de texto? Gracias


Detalles

  • Xcode 10.2.1 (10E1001), Swift 5

Solución 1

endEditing(_:)

let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:))) tableView.addGestureRecognizer(gesture)

Uso de la solución 1. Muestra completa

import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 30)) textField.borderStyle = .roundedRect textField.placeholder = "Enter text" textField.becomeFirstResponder() view.addSubview(textField) let gesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))) view.addGestureRecognizer(gesture) } }

Solución 2

clase TapGestureRecognizer

import UIKit class TapGestureRecognizer: UITapGestureRecognizer { let identifier: String init(target: Any?, action: Selector?, identifier: String) { self.identifier = identifier super.init(target: target, action: action) } static func == (left: TapGestureRecognizer, right: TapGestureRecognizer) -> Bool { return left.identifier == right.identifier } }

extensión UIView

import UIKit extension UIView { private var hideKeybordOnTapIdentifier: String { return "hideKeybordOnTapIdentifier" } private var hideKeybordOnTapGestureRecognizer: TapGestureRecognizer? { let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: hideKeybordOnTapIdentifier) if let gestureRecognizers = self.gestureRecognizers { for gestureRecognizer in gestureRecognizers { if let tapGestureRecognizer = gestureRecognizer as? TapGestureRecognizer, tapGestureRecognizer == hideKeyboardGesture { return tapGestureRecognizer } } } return nil } @objc private func hideKeyboard() { endEditing(true) } var hideKeyboardOnTap: Bool { set { let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(hideKeyboard), identifier: hideKeybordOnTapIdentifier) if let hideKeybordOnTapGestureRecognizer = hideKeybordOnTapGestureRecognizer { removeGestureRecognizer(hideKeybordOnTapGestureRecognizer) if gestureRecognizers?.count == 0 { gestureRecognizers = nil } } if newValue { addGestureRecognizer(hideKeyboardGesture) } } get { return hideKeybordOnTapGestureRecognizer == nil ? false : true } } }

Uso de la solución 2

view.hideKeyboardOnTap = true

Solución 2 muestra completa

import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 30)) textField.borderStyle = .roundedRect textField.placeholder = "Enter text" textField.becomeFirstResponder() view.addSubview(textField) view.hideKeyboardOnTap = true } }


// En Swift 4 ... Funcionó para mí.

func setupKeyboardDismissRecognizer(){ let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(searchingActivity.dismissKeyboard)) self.view.addGestureRecognizer(tapRecognizer) } @objc func dismissKeyboard() { view.endEditing(true) searchTableView.isHidden = true }

// Llame a esta función setupKeyboardDismissRecognizer () en viewDidLoad


Cada toque diferente del campo de texto descarta el teclado o usa resignfirstresponder

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; if(![touch.view isMemberOfClass:[UITextField class]]) { [touch.view endEditing:YES]; } }


Creé este método en Obj-C que oculta un teclado sin importar dónde esté escribiendo el usuario actualmente:

//call this method + (void)hideKeyboard { //grab the main window of the application UIWindow *window = [UIApplication sharedApplication].keyWindow; //call our recursive method below [self resignResponderForView:window]; } //our recursive method + (void)resignResponderForView:(UIView *)view { //resign responder from this view //If it has the keyboard, then it will hide the keyboard [view resignFirstResponder]; //if it has no subviews, then return back up the stack if (view.subviews.count == 0) return; //go through all of its subviews for (UIView *subview in view.subviews) { //recursively call the method on those subviews [self resignResponderForView:subview]; } }

Espero que eso sea traducible a Swift y tenga sentido. Se puede invocar en cualquier lugar de la aplicación y ocultará el teclado sin importar en qué VC se encuentre ni nada.


En Swift4

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


En este caso, hay UITapGesture como una de las opciones. Traté de crear un código de muestra por si acaso. Me gusta esto,

class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! @IBOutlet weak var scrollView: UIScrollView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let tapGesture = UITapGestureRecognizer(target: self, action: "tap:") view.addGestureRecognizer(tapGesture) } func tap(gesture: UITapGestureRecognizer) { textField.resignFirstResponder() } }


Esto funciona cuando se toca fuera del área de entrada para cualquier número de elementos de entrada.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.view.endEditing(true) }


Introduzca un reconocedor de gestos de toque y establezca y actúe para ello.

Usa el código:

nameofyourtextfield .resignfirstresponder ()


Mira esto.

override func viewDidLoad() { var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap)) self.view.userInteractionEnabled = true self.view.addGestureRecognizer(tapGesture) }

Entonces su controlador de grifo es.

func handleTap(sender: UITapGestureRecognizer) { self.view.endEditing(true) }


Para Swift 3

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


Prueba esto, está probado y funciona:

Para Swift 3.0 / 4.0

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

Para mayores Swift

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) { self.view.endEditing(true) }


Tuve el mismo problema y finalmente lo resolví.

Establezca un TapGestureRecognizer en su Storyboard y luego un Outlet en su ViewController

@IBOutlet var tapGesture: UITapGestureRecognizer!

Luego configure una IBAction en su ViewController

@IBAction func DismissKeyboard(sender: UITapGestureRecognizer) { self.view.endEditing(true) }

agregue estas líneas a su método viewDidLoad

override func viewDidLoad() { super.viewDidLoad() self.view.addGestureRecognizer(tapGesture) }

y debería funcionar

¡Espero que eso ayude!


Vaya a Tipo de teclado y seleccione Predeterminado o para lo que necesite el TextField. Luego, anule un método, llámelo como quiera, generalmente lo llamo touchBegins. A continuación se muestra lo que olvidó agregar.

super.touchingBegins(touches, withEvent: event) }


rápido 3

override func viewDidLoad() { super.viewDidLoad() self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))) }


Editado para Swift 4

Editar: Se agregó @objc . Si bien esta no es la mejor opción para el rendimiento, una instancia aquí no debería causar demasiados problemas hasta que haya una mejor solución.

Editado para corregir cuando necesita interactuar con elementos detrás de GestureRecognizer.

Editar: Gracias @Rao por señalar esto. Se agregó tap.cancelsTouchesInView = false .

Esto debería ayudarlo a tener múltiples UITextView o UITextField

Crea una extensión del controlador de vista. Esto ha funcionado mucho mejor para mí y con menos molestias que tratar de usar .resignFirstResponder()

extension UIViewController { func setupToHideKeyboardOnTapOnView() { let tap: UITapGestureRecognizer = UITapGestureRecognizer( target: self, action: #selector(UIViewController.dismissKeyboard)) tap.cancelsTouchesInView = false view.addGestureRecognizer(tap) } @objc func dismissKeyboard() { view.endEditing(true) } }

Llame a self.setupToHideKeyboardOnTapOnView() en viewDidLoad


Solución de trabajo para Swift 3 que funciona con ScrollView

class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! @IBOutlet weak var scrollView: UIScrollView! override func viewDidLoad() { super.viewDidLoad() // The next line is the crucial part // The action is where Swift 3 varies from previous versions let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tap(gesture:))) self.view.addGestureRecognizer(tapGesture) } func tap(gesture: UITapGestureRecognizer) { textField.resignFirstResponder() } }

Otra question que habla sobre este tema al que hice referencia y utilicé. La respuesta aceptada ya no funciona en Swift 3. La respuesta actual seleccionada debería ser la respuesta a continuación.


func findAndResignFirstResponder(_ stView: UIView) -> Bool { if stView.isFirstResponder { stView.resignFirstResponder() return true } for subView: UIView in stView.subviews { if findAndResignFirstResponder(subView) { return true } } return false }