Einleitung: Warum schließt sich die Tastatur nicht von selbst?
\nHallo, Entwicklerkollege! Wenn du jemals ein Anmeldeformular, eine Suchleiste oder einen Messenger unter iOS geschrieben hast, bist du sicherlich auf folgende Situation gestoßen: Der Benutzer hat Text eingegeben, aber die Tastatur hängt hartnäckig auf dem Bildschirm. Die "Fertig"-Taste wurde nicht gedrückt, der Benutzer tippt auf eine leere Stelle, aber nichts passiert. Ein Klassiker.
\n\nDies ist eines der beliebtesten Themen auf Stack Overflow, wo die Frage "Close iOS Keyboard by touching anywhere using Swift" tausende Aufrufe erhalten hat. Das Problem liegt nicht darin, dass es schwierig zu implementieren wäre. Das Problem ist, dass Anfänger (und nicht nur sie) oft falsche oder "unsaubere" Methoden wählen. Lass uns die Top-3-Fehler analysieren und uns dann drei korrekte, funktionierende Lösungen ansehen.
\n\nHeute sprechen wir über Swift und UIKit. Wenn du SwiftUI verwendest – schau auch vorbei, die Prinzipien sind ähnlich.
\n\nFehler Nr. 1: "TapGesture auf alles und jeden legen"
\nDer häufigste Fehler – einen UITapGestureRecognizer auf die UIView zu legen, aber zu vergessen, cancelsTouchesInView zu deaktivieren. In der Folge reagieren Buttons und Tabellen nicht mehr auf Berührungen. Der Benutzer tippt auf den "Senden"-Button, aber stattdessen wird die Tastatur geschlossen, nicht das Formular abgeschickt.
Beispiel für falschen Code:
\noverride 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\nAuf den ersten Blick – alles okay. Aber in der Praxis, wenn du eine UITableView oder einen UIButton hast, können deren Berührungen von dieser Geste "verschluckt" werden. Besonders auffällig wird das, wenn du eine solche Geste auf eine scrollView legst.
Wie man es behebt:
\nFüge die Zeile tap.cancelsTouchesInView = false hinzu. Dadurch können andere UI-Elemente weiterhin Berührungsereignisse empfangen.
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))\ntap.cancelsTouchesInView = false\nview.addGestureRecognizer(tap)\n\nAber selbst das ist keine ideale Lösung, wenn du eine komplexe Oberfläche hast.
\n\nFehler Nr. 2: "Tap auf leere Stelle zerstört die Tabelle"
\nDas zweite häufige Problem – eine falsche Interaktion mit UIScrollView oder UITableView. Wenn du einen UITapGestureRecognizer auf die view legst, die eine Tabelle enthält, kann bei einem Tap auf eine Zelle sowohl die Geste als auch die Methode didSelectRow gleichzeitig ausgelöst werden. Oder, noch schlimmer, die Geste fängt die Berührung ab, und die Zelle wird nicht markiert.
Lösung: Verwende UIGestureRecognizerDelegate
\nImplementiere die Methode gestureRecognizer(_:shouldReceive:) und prüfe, ob der Tap auf ein Textfeld oder ein anderes Element erfolgte. Wenn die Berührung auf ein UITextField oder UITextView fällt – blockiere die Geste nicht.
extension ViewController: UIGestureRecognizerDelegate {\n func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {\n // Berührungen nicht abfangen, wenn sie auf ein Textfeld fallen\n if touch.view is UITextField || touch.view is UITextView {\n return false\n }\n return true\n }\n}\n\nJetzt wird die Geste nur bei einem Tap auf leere Bereiche ausgelöst, während Textfelder interaktiv bleiben.
\n\nFehler Nr. 3: "Die Rückkehr von der Tastatur vergessen"
\nViele Entwickler implementieren das Schließen per Tap, vergessen aber den "Return"-Button (Enter) auf der Tastatur. Der Benutzer könnte "Fertig" drücken und erwarten, dass sich die Tastatur schließt. Wenn das nicht passiert, erhältst du eine negative UX.
\n\nWie man es behebt:
\nAbonniere das Protokoll UITextFieldDelegate und implementiere die Methode textFieldShouldReturn:
class View