Using protocol extension to dismiss keyboard on outside tap
Using protocol extension to dismiss keyboard on outside tap
- Subject: Using protocol extension to dismiss keyboard on outside tap
- From: Devarshi Kulshreshtha <email@hidden>
- Date: Mon, 18 Apr 2016 13:37:23 +0530
In my project I have few view controllers which are subclasses of
UITableViewController, UIViewController, on each I want to implement this
behavior:
> When user taps outside of a text field it should dismiss the keyboard
which was visible when user tapped inside it.
I can easily implement it by defining a tap gesture recognizer and
associating a selector to dismiss the keyboard:
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)
}
}
Since I have to implement same behavior in multiple view controllers, I am
trying to identify a way to avoid using repetitive code in multiple classes.
One option for me is to define a `BaseViewController`, which is subclass of
`UIViewController`, with all above methods defined within it and then
subclass each of my view controller to `BaseViewController`. The problem
with this approach is that I need to define two `BaseViewController`s one
for `UIViewController` and one for `UITableViewController` since I am using
subclasses of both.
The other option which I am trying to use is - `Protocol-Oriented
Programming`. So I defined a protocol:
protocol DismissKeyboardOnOutsideTap {
var backgroundView: UIView! { get }
func configureToDismissKeyboard()
func hideKeyboard()
}
Then defined its extension:
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)
}
}
In my view controller I confirmed to the protocol:
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 is - above code is crashing with exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[MyProject.MyViewController hideKeyboard]: unrecognized selector
sent to instance 0x7f88c1e5d700'
To avoid this crash I need to redefine `hideKeyboard` function within
`MyViewController`class, which is defeating my purpose of avoiding
repetitive code :(
Please suggest if I am doing any thing wrong over here or is there any
better way to implement my requirement.
--
Thanks,
Devarshi
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden