Detect when taps are outside of a UITextView - ios

I am working on a program where I have various UITextViews. The problem I am having is that I cannot detect when the user has tapped outside of the UITextView so that I can hide the keyboard. I have tried various actions, but none of them work.
Code I am using with actions:
#IBAction func touchOutsideTextField(sender: UITextField)
{
sender.resignFirstResponder()
}
What should I be doing to hide the keyboard instead of this?

You can use UITapGestureRecognizer For that.
add TapGesture into View and when View is tapped that time keyBoard will hide.
Here is the sample code for you.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var text: UITextView!
#IBOutlet weak var text2: UITextView!
#IBOutlet weak var text3: UITextView!
#IBOutlet weak var text4: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
let aSelector : Selector = "touchOutsideTextField"
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector)
tapGesture.numberOfTapsRequired = 1
view.addGestureRecognizer(tapGesture)
}
func touchOutsideTextField(){
self.view.endEditing(true)
}
}
Or you can use touchesBegan method for it add this code if you want to try this way.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
With this code you don't need to add UITapGestureRecognizer.
You can choose one of this option.

For those still using Obj C here is the translation:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[self.view endEditing:TRUE];
}
Apple says in their documentation that if you omit the call to super, then you must also override the other touch methods...even if you don't use them. For more on that here is the link: touchesBegan:withEvent:

Related

Best way to dismiss keyboard when tapping outside of UITextField - IOS

I've found a few threads here about this, and some videos online about it as well, but every solution seems to have problems reported by others. The simplest solution I've found is the one below.
import UIKit
class SignupController: UIViewController, UITextFieldDelegate {
// Outlets
#IBOutlet weak var logoImage: UIImageView!
#IBOutlet weak var nameTF: CustomTextField!
#IBOutlet weak var emailTF: CustomTextField!
#IBOutlet weak var passwordTF: CustomTextField!
#IBOutlet weak var confirmPassTF: CustomTextField!
// Actions
#IBAction func signupButton(_ sender: UIButton) {
}
override func viewDidLoad() {
super.viewDidLoad()
logoImage.image = UIImage(named: "logo2")
nameTF.delegate = self
emailTF.delegate = self
passwordTF.delegate = self
confirmPassTF.delegate = self
}
// Moves to next text field each time return key is pressed
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == nameTF {
textField.resignFirstResponder()
emailTF.becomeFirstResponder()
} else if textField == emailTF {
textField.resignFirstResponder()
passwordTF.becomeFirstResponder()
} else if textField == passwordTF {
textField.resignFirstResponder()
confirmPassTF.becomeFirstResponder()
}else if textField == confirmPassTF {
textField.resignFirstResponder()
}
return true
}
// Dismisses keyboard when tapped
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
It works, is very simple, but my project and coding experience are in their infancy, so I'm not sure if this is the best method simply because it's short, or if there's something I'm missing due to lack of experience/knowledge?
Anybody know of a better solution, or is this one just fine?
just do this:
class viewController: UIViewController, UITextFieldDelegate {
// Outlets
#IBOutlet weak var logoImage: UIImageView!
#IBOutlet weak var nameTF: CustomTextField!
#IBOutlet weak var emailTF: CustomTextField!
#IBOutlet weak var passwordTF: CustomTextField!
#IBOutlet weak var confirmPassTF: CustomTextField!
// Actions
#IBAction func signupButton(_ sender: UIButton) {
}
override func viewDidLoad() {
super.viewDidLoad()
logoImage.image = UIImage(named: "logo2")
nameTF.delegate = self
emailTF.delegate = self
passwordTF.delegate = self
confirmPassTF.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dissMissKeyboard))
view.addGestureRecognizer(tap)
}
func dissMissKeyboard() {
view.endEditing(true)
}
I prefer to use UITextField delegate method:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
view.endEditing(true)
return true
}
or setup inputAccessoryView which have 'done' or 'exit' button.
Then you need to implement the gesture recognition for this . Or you can do like this :
override func viewDidLoad() {
super.viewDidLoad()
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dissMissKeyboard))
//Uncomment the line below if you want the tap not not interfere and cancel other interactions.
//tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
//Calls this function when the tap is recognized.
func dissMissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}

Swift 3 Gestures + TouchesBegan BUG?

I am using xcode 8.0 & Swift 3.
Here's the overview of my issue:
Scrollview with an imageview named "insidepic" as a subview.
a duplicate of the imageview named "outsidepic" is positioned outside the scrollview.
When "outsidepic" is tapped, touchesBegan is fired.
When "insidepic" is tapped, the tap gesture is fired...but not touchesBegan or touchesEnded are fired.
Here's what I need to solve:
I need for touchesBegan to get fired when the scrollview is tapped. I have added the ".cancelsTouchesInView = false" to the gesture.
Furthermore, the zoom/pan gesturing on the scrollview needs to stay intact. So userinteraction is enabled on both the scrollview & the imageview inside.
This see attached image shows the layout & the viewcontroller swift file.
The yellow area is the scrollview. (with "insidepic" inside)
But, for quick reference, here is my code:
import UIKit
var tap = UITapGestureRecognizer()
class ViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate {
#IBOutlet weak var scroller: UIScrollView!
#IBOutlet weak var insidepic: UIImageView!
#IBOutlet weak var outsidepic: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
scroller.minimumZoomScale = 1
scroller.maximumZoomScale = 6
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
tap.numberOfTapsRequired = 1;
tap.numberOfTouchesRequired = 1;
tap.delegate = self
tap.cancelsTouchesInView = false
scroller.addGestureRecognizer(tap)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("Touches Began")
}
func handleTap(){
print("Tap Gesture Received")
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return insidepic
}
}
MANY THANKS FOR ANY HELP OR INSIGHT YOU CAN OFFER!!

tap gesture recognizer does not get fire

I want to implement an action, when if the user tap somewhere on the screen, then the keyboard should disappear.
I have an app, that look as follow
When I tap on textfield then the keyboard appears, that is good.
Now I want, when I tap somewhere on the screen, then the keyboard should disappear.
I implemented a tap gesture recognizer with following property value:
And the tap gesture recognizer I bound with following action in the view controller
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var nameField: UITextField!
#IBOutlet weak var numberField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func textFieldDoneEdition(sender: UITextField) {
sender.resignFirstResponder()
}
#IBAction func onTapGestureRecognized(sender: AnyObject) {
nameField.resignFirstResponder()
numberField.resignFirstResponder()
}
}
Tap gesture recognizer is bound to the function.
And it does not work at all, when I tap somewhere on the screen. The keyboard is still there. What am I doing wrong?
Your view should have the Gesture associated.
Your Gesture should have Sent actions
This should be enough to work.
If for some mystical reason, none of this works, you have an alternative for dismiss keyboard.
func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)

dismissing keyboard on return key and also on press outside textfield/text view

I have a screen with a textField and a textView.
I want the textField keyboard to be dismissed on the press of the return key or if a user taps on a blank area of the screen.
Tutorials have shown me to do the following:
#IBOutlet weak var DescriptionContent: UITextView!
#IBOutlet weak var TitleContent: UITextField!
func textFieldShouldReturn(TitleContent: UITextField) -> Bool {
TitleContent.resignFirstResponder()
return false
}
On the storyboard I have clicked on the textField and ctrl dragged a delegate to the yellow icon above my view controller containing the textField.
This did not work.
I have seen on stack overflow to also try:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
TitleContent.resignFirstResponder()
}
super.touchesBegan(touches , withEvent:event)
}
And that didn't work and then I saw to try the following inside the view controllers viewdidload method:
let tapper = UITapGestureRecognizer(target: self.view, action:Selector("endEditing:"))
tapper.cancelsTouchesInView = false
self.view.addGestureRecognizer(tapper);
And that did not work either. The first line of my controller is the following:
class PostController: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate, UITextFieldDelegate, UITextViewDelegate { ...
And inside my viewDidLoad I have the following:
DescriptionContent.delegate = self
TitleContent.delegate = self
Ultimately I want the user to be able to dismiss the keyboard by pressing outside the textfield and likewise with my textview.
The way I got this to work was by adding this into the viewDidLoad function
var tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
view.addGestureRecognizer(tap)
and by creating a method called DismissKeyboard which just calls
view.endEditing(true)
This makes it such that if you click anywhere on the screen, that is not the text fields it will close the first responder.
In the textFieldShouldReturn function it should be returning true, if its returning false, it won't cause the first responder to close.
Hope I helped a bit...
I am providing a couple of options that you may want for later.
First how move to new view controller.
#IBOutlet var passCodeText: UITextField! // Make sure you have have this
func textFieldShouldReturn(textField: UITextField) -> Bool {
passCodeText.resignFirstResponder()
self.performSegueWithIdentifier("tableVC", sender: self)
return true
}
To love your main issue.
UITextFieldDelegate // make sure to add this to your class line
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true);
}

Swift UIScrollView : keyboard doesn't dismiss interactively

I want to dismiss the keyboard interactively, but my code is not working. I don't know why.
When I try the keyboard dismiss mode onDrag it is working fine and there is no need of any more code for that.
Here is my code :
import UIKit
class LoginViewController: UIViewController, UITextFieldDelegate{
#IBOutlet weak var txtUserName: UITextField!
#IBOutlet weak var txtPassword: UITextField!
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBarHidden = false;
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive
// Do any additional setup after loading the view.
}
#IBAction func LoginTapped(sender: AnyObject)
{
//here my code which is running
}
func textFieldShouldReturn(textField: UITextField!) -> Bool { //delegate method
textField.resignFirstResponder()
return true
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive
}
}
Here are screenshots of the simulator
Please take a look and if possible let me know where the error is.
Use this code. This will end editing when you tap anywhere on the screen.
override func viewDidLoad() {
super.viewDidLoad()
//Looks for single or multiple taps.
var tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
view.addGestureRecognizer(tap)
}
//Calls this function when the tap is recognized.
func DismissKeyboard(){
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
Hope that helps.
I had the same problem and i finally solved it !
For me the Julian's solution didn't worked so i had to do it as it is :
Set a TapGestureRecognizer in your Storyboard and then an Outlet in your ViewController
#IBOutlet var tapGesture: UITapGestureRecognizer!
Then set an IBAction in your ViewController
#IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
self.view.endEditing(true)
}
add these lines to your viewDidLoad method
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addGestureRecognizer(tapGesture)
}
and its should work
Hope that will help !
The below code will work on all the components in the UIView for all the UITextField
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}

Resources