In meinem Projekt entlassen ich einige View-Controller haben, die Unterklassen von UITableViewController sind, UIViewController, auf jedes ich dieses Verhalten implementieren möchten:Protokollerweiterung Mit Tastatur auf außerhalb tippen
Wenn Benutzer außerhalb eines Textes tippt Feld sollte es die Tastatur zu entlassen, die sichtbar war, wenn der Benutzer in es klopfte.
Ich kann es leicht implementieren, indem eine Anzapfung Gestenerkenner definiert und einen Selektor Zuordnen der Tastatur zu entlassen:
class MyViewController {
override func viewDidLoad() {
super.viewDidLoad()
configureToDismissKeyboard()
}
private func configureToDismissKeyboard() {
let tapGesture = UITapGestureRecognizer(target: self, action: "hideKeyboard")
tapGesture.cancelsTouchesInView = true
form.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
form.endEditing(true)
}
}
Da ich gleiche Verhalten in mehreren View-Controller zu implementieren haben, versuche ich zu identifizieren eine Möglichkeit, sich wiederholenden Code in mehreren Klassen zu vermeiden.
Eine Option für mich ist eine BaseViewController
zu definieren, die eine Unterklasse von UIViewController
ist, mit allen oben genannten Methoden definiert und dann jede meiner View-Controller Unterklasse BaseViewController
. Das Problem mit diesem Ansatz ist, dass ich zwei BaseViewController
s eins für UIViewController
und eins für UITableViewController
definieren muss, da ich Unterklassen von beiden verwende.
Die andere Option, die ich versuche zu verwenden, ist - Protocol-Oriented Programming
. So I definiert ein Protokoll:
protocol DismissKeyboardOnOutsideTap {
var backgroundView: UIView! { get }
func configureToDismissKeyboard()
func hideKeyboard()
}
Dann seine Erweiterung definiert:
extension DismissKeyboardOnOutsideTap {
func configureToDismissKeyboard() {
if let this = self as? AnyObject {
let tapGesture = UITapGestureRecognizer(target: this, action: "hideKeyboard")
tapGesture.cancelsTouchesInView = true
backgroundView.addGestureRecognizer(tapGesture)
}
}
func hideKeyboard() {
backgroundView.endEditing(true)
}
}
Meiner Ansicht Controller ich dem Protokoll bestätigt:
class MyViewController: UITableViewController, DismissKeyboardOnOutsideTap {
var backgroundView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// configuring background view to dismiss keyboard on outside tap
backgroundView = self.tableView
configureToDismissKeyboard()
}
}
Problem ist - oben Code stürzt mit Ausnahme:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyProject.MyViewController hideKeyboard]: unrecognized selector sent to instance 0x7f88c1e5d700'
diesen Absturz zu vermeiden ich hideKeyboard
Funktion innerhalb MyViewController
Klasse neu definieren muß, was meinen Zweck der Vermeidung repetitiven Code besiegt :(
Bitte legen nahe, wenn ich falsch hier irgend etwas tue, oder gibt es eine bessere Möglichkeit, meine zu implementieren Anforderung.
Es scheint so, als ob Sie von MyViewController aus die Funktion hideKeyboard in Ihren BaseViewControllern wiederverwenden möchten. Aber Sie haben Ihren MyViewController nicht als Unterklasse von BaseViewControllern deklariert. –
Hey vielen Dank für Ihre Antwort, aber bitte beachten Sie, dass die Verwendung von 'BaseViewController' die erste Option war, die ich aus Gründen vermeiden möchte, die in meiner geposteten Frage angegeben sind. Momentan versuche ich 'protokollorientierte Programmierung' zu verwenden :) – Devarshi
Wenn Sie eine protokollorientierte Programmierung verwenden, müssen Sie das hideKeyboard in Ihrem MyViewController implementieren und sich wiederholenden Code haben. Das Protokoll hilft Ihnen, nur das zu formulierende "Protokoll" zu definieren. –