Cerrando el teclado de iOS con un toque: antipatrones y 3 soluciones funcionales en Swift

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué el teclado no se cierra solo?

\n

¡Hola, colega desarrollador! Si alguna vez has escrito un formulario de inicio de sesión, una barra de búsqueda o un mensajero en iOS, seguramente te has encontrado con esta situación: el usuario ha ingresado texto, pero el teclado se queda obstinadamente en la pantalla. El botón "Listo" no se ha presionado, el usuario toca un espacio vacío, pero no sucede nada. Un clásico.

\n\n

Este es uno de los temas más populares en Stack Overflow, donde la pregunta "Close iOS Keyboard by touching anywhere using Swift" ha acumulado miles de visitas. El problema no es que sea difícil de hacer. El problema es que los principiantes (y no solo ellos) a menudo eligen formas incorrectas o "sucias". Analicemos los 3 errores principales y luego veamos tres soluciones correctas y funcionales.

\n\n

Hoy hablamos de Swift y UIKit. Si usas SwiftUI, también échale un vistazo, los principios son similares.

\n\n

Error n.º 1: "Ponemos TapGesture en todo"

\n

El error más común es agregar un UITapGestureRecognizer a la UIView, pero olvidar desactivar cancelsTouchesInView. Como resultado, los botones y las tablas dejan de responder a los toques. El usuario toca el botón "Enviar", pero se activa el cierre del teclado, no el envío del formulario.

\n\n

Ejemplo de código incorrecto:

\n
override func viewDidLoad() {\n    super.viewDidLoad()\n    let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))\n    view.addGestureRecognizer(tap)\n}\n\n@objc func dismissKeyboard() {\n    view.endEditing(true)\n}
\n\n

A primera vista, todo está bien. Pero en la práctica, si tienes una UITableView o un UIButton, sus toques pueden ser "tragados" por este gesto. Esto es especialmente notable cuando agregas dicho gesto a un scrollView.

\n\n

Cómo solucionarlo:

\n

Agrega la línea tap.cancelsTouchesInView = false. Esto permitirá que otros elementos de la interfaz reciban eventos táctiles.

\n\n
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))\ntap.cancelsTouchesInView = false\nview.addGestureRecognizer(tap)
\n\n

Pero incluso esto no es una solución ideal si tienes una interfaz compleja.

\n\n

Error n.º 2: "Tocar un espacio vacío rompe la tabla"

\n

El segundo problema popular es la interacción incorrecta con UIScrollView o UITableView. Si agregas un UITapGestureRecognizer a la view que contiene una tabla, al tocar una celda puede activarse simultáneamente el gesto y el método didSelectRow. O, peor aún, el gesto interceptará el toque y la celda no se resaltará.

\n\n

Solución: usa UIGestureRecognizerDelegate

\n

Implementa el método gestureRecognizer(_:shouldReceive:) y verifica si el toque fue en un campo de texto o en otro elemento. Si el toque fue en un UITextField o UITextView, no bloquees el gesto.

\n\n
extension ViewController: UIGestureRecognizerDelegate {\n    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {\n        // No interceptamos toques si son en un campo de texto\n        if touch.view is UITextField || touch.view is UITextView {\n            return false\n        }\n        return true\n    }\n}
\n\n

Ahora el gesto solo se activará al tocar áreas vacías, y los campos de texto permanecerán interactivos.

\n\n

Error n.º 3: "Olvidamos el retorno del teclado"

\n

Muchos desarrolladores implementan el cierre con un toque, pero olvidan el botón "Return" (Enter) del teclado. El usuario puede presionar "Listo" y esperar que el teclado se cierre. Si no se hace esto, obtendrás una mala experiencia de usuario (UX).

\n\n

Cómo solucionarlo:

\n

Suscríbete al protocolo UITextFieldDelegate e implementa el método textFieldShouldReturn:

\n\n
class View                

Blogs

Book Recommendations