How to Dismiss keyboard when touching away across the entire app - ios

I have multiple textFields in different viewControllers where keyboard is popped up.
I know how to dismiss keyboard when user clicks on a different part of the screen but I don't want to go and hard code it into every corner of my app.
So is there anyway to enforce keyboard getting keyboard dismissed everywhere on the app when the user clicks anywhere on the screen other than keyboard?
I was thinking of extending the UIViewController, but I also have some textFields inside a view that I add as a subview. Perhaps there could be someway that I extend TextField class itself?

I suggest to create a base UIViewController and let each of your ViewControllers inherit it; override touchesBegan method in it:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
view.endEditing(true)
}
OR you can override viewDidLoad -in the base ViewController- and add a UITapGestureRecognizer to the view, as follows:
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(Base.endEditing))
view.addGestureRecognizer(tapGesture)
}
func endEditing() {
view.endEditing(true)
}

You can also use an extension of a view controller, if you want the keyboard dismissal to apply to all of them:
extension UIViewController {
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}

Related

Close iOS Keyboard by touching outside ( a smarter way)

I have UIViewController with UITextfield and several other elements (several subviews and buttons). I want to close the keyboard when tapped somewhere outside of the UITextfield.
I know there is an answer Close iOS Keyboard by touching anywhere using Swift, but this way doesn't work if user taps on viewController's subviews or buttons.
I can add the similar UITapGestureRecognizer for each subViews and buttons, but is there a smarter way to resolve this?
extension UIViewController{
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
Also if you have elements in a UIScrollView, add this method too:
extension UIScrollView {
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.next?.touchesBegan(touches, with: event)
}
}

How to trigger an event when a user touches specific part of the screen - ios?

I have a custom pop up which I have made using a UIViewController (presentation: 'over current context') - please see below. What I would like to do is dismiss the UIViewController once the user touches the top - dark half- of the screen, which does not contain the menu options. What event can i trigger to get this to work?
You can add a tap gesture to the darkView and inside it do
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
mydarkView.addGestureRecognizer(tapGesture)
//
// 3. this method is called when a tap is recognized
#objc func handleTap(_ sender: UITapGestureRecognizer) {
self.dismiss(animated:true,completion:true)
}
OR use
override func touchesBegan(_ touches: Set<UITouch>,
with event: UIEvent?)

How to hide keyboard in swift on press of navigationBar

I am developing an swift 3 app that has a navigation bar in every page. The navigation bar also has a button in the left.
I need to resign the keyboard on touch of any object in the screen.
I tried with the usual
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
but it works for all other parts of the view except the navigation bar.
I tried adding the following code:
self.navigationController?.navigationBar.endEditing(true)
to the touchesBegan function but it did not work, presumable because I do not have a navigation controller, I just added the searchbar in the storyboard.
How can I get the keyboard to resign on tap of the navigation bar, including the button in the navigation bar?
This is important to my app, because, as you can see below, it is the largest space available for the user to tap without changing the view.
I need to make the resigning work in the area enclosed in yellow, including the button shown by the arrow.
for e.g
override func viewDidLoad() {
super.viewDidLoad()
let hideKeyboard = UITapGestureRecognizer(target: self, action: #selector(self.navigationBarTap))
hideKeyboard.numberOfTapsRequired = 1
navigationController?.navigationBar.addGestureRecognizer(hideKeyboard)
}
and handle the action as
func navigationBarTap(_ recognizer: UIGestureRecognizer) {
view.endEditing(true)
// OR USE yourSearchBarName.endEditing(true)
}
Try to add tap gesture on navigation bar :
override func viewDidLoad() {
super.viewDidLoad()
let navSingleTap = UITapGestureRecognizer.init(target: self, action: #selector(self.tap(_:)))
navSingleTap.numberOfTapsRequired = 1
self.navigationController?.navigationBar.subviews[1].isUserInteractionEnabled = true
self.navigationController?.navigationBar.subviews[1].addGestureRecognizer(navSingleTap)
}
func tap() {
// do your work
}
Subclass UINavigationBar and set it as the custom class of the Navigation Bar in the Storyboard.
// NavigationBar.swift
import UIKit
class NavigationBar: UINavigationBar {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.window?.endEditing(true)
}
}
Call this line inside of your button action BEFORE you are calling your MENU on button:
YourSearchOutlet.resignFirstResponder()

Dismissing Keyboard for UITextField

I'm new to Swift, and I was recently learning about UITextField and how it delegates. I was wondering if there was a simple way to dismiss the keyboard when taping outside of it (somewhere else in the view). Currently, I am using UITapGestureRecognizer to do this. It works, but I was wondering if there was a simpler way to do it.
You can use this method to dismiss the keyboard by tapping anywhere on the screen
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
But be sure to set the delegates beforehand.
Set the delegate of UITextField, Like as UITableviewDataSource,Delegate. Write yourTextFieldDelegate.delegate = self in viewDidLoad()
Then, write this function:
func textFieldShouldReturn(textField: UITextField) -> Bool {
titleTextField.resignFirstResponder()
return true
}

touchesbegan for dismissing keyboard textview under scrollview not working

I have a text field under a view which is under a scroll view inside a view controller which is one of the view controllers of a navigation controller. I want to dismiss the keyboard when the user touches outside the textfield. I tried using touchesBegan:, but it is not firing when it's under the scrollview. I also tried disabling user interaction in the scroll view, but nothing worked. Could anyone help me out?
func dismissKeyboard(txtField:UITextField)
{
txtField.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
dismissKeyboard(firstNameTxt)
}
Changed the below way for it to work
extension AddEditHireViewController {
func hideKeyboard()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: "dismissKeyboardNew")
self.formView.addGestureRecognizer(tap)
}
func dismissKeyboardNew()
{
self.formView.endEditing(true)
// self.dismissKeyboard(self.firstNameTxt)
} }
Whilst the solution given by Matthew Bradshaw works too, it will not dismiss the keyboard if the user scrolls. If you want it to do that, another solution would be to subclass UIScrollView. You could then override the touchesBegan method in this subclass, and then end editing accordingly.
class DismissableScrollView: UIScrollView {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
endEditing(false)
}
}
Once you have done this, simply change your existing UIScrollView's class to DismissableScrollView, or if you are already subclassing UIScrollView, you could add this to that subclass.
You could try to create an extension of the view controller. This has worked much smoother for me and with less hassle than trying to use .resignFirstResponder()
extension UIViewController
{
func hideKeyboard()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
func dismissKeyboard()
{
view.endEditing(true)
}
}
Call self.hideKeyboard() in the viewDidLoad

Resources