Close iOS Keyboard by touching outside ( a smarter way) - ios

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)
}
}

Related

How can I include multiple UITextFields in the Hidekeyboard function given below?

I am trying to implement a function that can let decimal pads disappear when the user clicks somewhere else but the keyboard. The issue is that I currently only know this function which to my knowledge only works for 1 textField:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.Alkoholanteil.endEditing(true)
}
I could only enter the text field "Referencetime" as you could see.
Is there a function that allows for the keyboards to disappear when the user is touching else but the keyboard for 4 text fields and not 1?
You can do it with:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
Which will work for all textField.

Swift UIScrollView scroll gesture does not call touchesMoved

I really need touchesMoved(...) method in UIScrollView. I know that there is a method scrollViewDidScroll(...), but I really need the other method.
So I create subclass of UIScrollView and implement those methods.
class MyScrollView: UIScrollView {
...
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
print("Move")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
print("Touch")
}
}
If I click on the scroll view I get (let say I click two times) :
Touch
Touch
If I click on scroll view and wait a second and then move my finger I get :
Touch
Move
Move
But then scroller start to scroll and I don't receive anything anymore.
Why scroll gesture doesn't call those methods?
How do I persuade scroll view to call those methods on scroll?

Could I set vc's view becomeFirstResponder by touchesBegan func in storyboard?

In code, I can use this below method to let vc's view becomeFirstResponder, and play down the show-up keyboard.
the code is below:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
Could I set this function in my storyboard? or there is some way easier for self.view.endEditing(true) when click self.view?
Because if not do this, I will copy the function upper to almost every vc.
Just put this somewhere in the code and it would resolve your issue with code duplicating
extension UIViewController {
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.view.endEditing(true)
}
}
I'm not sure tho if it's a good way of doing this, maybe you'd like to rethink the architectural issues of resigning the textfield's responder, regards of what you really need.
You can create an extension of UIViewController and then make swizzling methods for touchesBegans and your own customTouchBegans. see an example of swizzling methods for viewWillAppear
https://www.uraimo.com/2015/10/23/effective-method-swizzling-with-swift/

How to hide keyboard by touch in the screen if all my main view is cover by another views?

I cant touch in my main view, I have few other views on him.
this func :
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
dose'nt help me..
is there any func?
If you know which View is focused you can call resignFirstResponder() on it

How to Dismiss keyboard when touching away across the entire app

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)
}
}

Resources