Reputation: 100
I need to be able to tap out of the keyboard when not tapping in uitextfield or when not tapping show/hide password button.
I was previously using this code to do that:
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
}
But the problem with that was that it clicks out of the keyboard even when clicking the show/hide password eye icon. The code I'm using for the show/hide icon is this:
extension UITextField {
func showhidepasswordbutton(image: UIImage = UIImage(systemName: "eye.slash")!) {
let button = UIButton(type: .custom)
button.setImage(image, for: .normal)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
button.addTarget(self, action: #selector(self.refreshforshowhide), for: .touchUpInside)
button.tintColor = .darkGray
self.rightView = button
self.rightViewMode = .always
}
@IBAction func refreshforshowhide(_ sender: Any) {
print("ok")
if self.isSecureTextEntry == true {
self.togglePasswordVisibility()
showhidepasswordbutton(image: UIImage(systemName: "eye")!)
} else if self.isSecureTextEntry == false {
self.togglePasswordVisibility()
showhidepasswordbutton(image: UIImage(systemName: "eye.slash")!)
}
}
func togglePasswordVisibility() {
let temptext = self.text
isSecureTextEntry.toggle()
self.text = ""
self.text = temptext
}
}
Sorry for the messy code, just wrote the show/hide password code up.
Upvotes: 0
Views: 102
Reputation: 16341
You could exclude the taps on subviews using gestureRecognizer(_:, shouldReceive:)
method in UIGestureRecognizerDelegate
.
extension UIViewController: UIGestureRecognizerDelegate {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
tap.delegate = self
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
touch.view?.isDescendant(of: view) == false // will return false if touch was received by a subview
}
}
Update: You could use touch.view == view
instead of touch.view?.isDescendant(of: view) == false
.
Upvotes: 1