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