Swift UIScrollView : keyboard doesn't dismiss interactively - ios

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];
}
}
}

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!!

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

Detect when taps are outside of a UITextView

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:

hide keyboard for text field in swift programming language

I have little experience in Objective-C. I want to hide the keyboard for a text field using the Swift programming language.
I also tried this
func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
return true;
}
But the method is not getting triggered when I hit return. Anyone have any luck with this?
I think the Problem is with setting the Delegate.
Please set textfield Delegate to your ViewController like this
class ViewController: UIViewController,UITextFieldDelegate {
and then create the IBOutlet for your text field like this
#IBOutlet var txtTest : UITextField = nil
make sure that it is connected to your text field on your view in storyboard.
finally set its Delegate using
txtTest.delegate=self
We are almost done. Now place this delegate function into your class.
func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
textField.resignFirstResponder()
return true;
}
Hope this will solve your issue.
Just override the UIViewController method called "touchesBegan" and set endEditing to true. Just like this:
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
self.view.endEditing(true)
}
In order to hide the keyboard when you pressed a button, you need to use the following function.
self.view.endEditing(true)
This works when a button is pressed.
Hope this helps someone out there.
Here we go:
Add a textField to your View
Create a new Swift file
Set this new file as a Class for that particular View
Add a TextField to your View
Create an Outlet for the textfield (my is named "txtField" !)
Substitute any code in the Swift Class file with this:
import Foundation
import UIKit
//01 create delegation
class MyViewController2: UIViewController,UITextFieldDelegate {
#IBOutlet weak var txtField: UITextField!=nil
override func viewDidLoad() {
super.viewDidLoad()
// additional setup after loading the view
//02 set delegate to textfield
txtField.delegate = self
}
//03 textfield func for the return key
func textFieldShouldReturn(textField: UITextField) -> Bool {
txtField.resignFirstResponder()
return true;
}
//textfield func for the touch on BG
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
txtField.resignFirstResponder()
self.view.endEditing(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
//dispose of any resources that can be recreated
}
}
Try it out, be happy & say thanks !
Now In Swift 3/4/5, the easiest methods are
Method 1: called when 'return' key pressed.
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
textField1.resignFirstResponder()
textField2.resignFirstResponder()
return true;
}
Method 2: called when 'return' key pressed.
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
self.view.endEditing(true)
return true;
}
Method 3: Global Method Write in view did load
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
Note: Don't forget to add this. Other wise its not work.
UIGestureRecognizerDelegate, UITextFieldDelegate
I hope it will work for you :)
In simple way to hide the keyboard just override the UIView "touchBegan method". So when you tap any where in the view keyboard is hide.
here is the sample code.. (Swift 3.0 Updated code)
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
self.view.endEditing(true)
}
Like #spfursich said, The best way is, when user touch anywhere above the keyboard the keyboard will disappear. Here is the code :
override func viewDidLoad() {
super.viewDidLoad()
var tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
self.view.addGestureRecognizer(tap)
}
func DismissKeyboard(){
self.view.endEditing(true)
}
Add UITextFieldDelegate to the class declaration:
class ViewController: UIViewController, UITextFieldDelegate
Connect the textfield or write it programmatically
#IBOutlet weak var userText: UITextField!
set your view controller as the text fields delegate in view did load:
override func viewDidLoad() {
super.viewDidLoad()
self.userText.delegate = self
}
Add the following function
func textFieldShouldReturn(userText: UITextField!) -> Bool {
userText.resignFirstResponder()
return true;
}
with all this your keyboard will begin to dismiss by touching outside the textfield aswell as by pressing return key.
UIApplication.sharedApplication().sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, forEvent:nil)
First you need to set delegate for your textfield then you need to include resignFirstResponder() to hide keyboard when press return button of keybaord.
func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
textField .resignFirstResponder()
return true;
}
You can try this code to have the "return" key execute code.
func textFieldShouldReturn(textField: UITextField) -> Bool{
textField.resignFirstResponder()
performAction()
return true;
}
func performAction(){
//execute code for your action inside this function
}
Hope this can help you.
You can also do like this:
add event "Did end on exit" from connections inspector of your TextField
and connect it to method from relevant ViewController
In my example I connect it to method called 'ended'
declare sender as UITextField and then call sender.resignFirstResponder();
Like this:
#IBAction func ended (sender: UITextField){ sender.resignFirstResponder(); }
Here i have solved the problem, that when keypad opens and the view gets hidden behind the keypad.... that time we need to change the UI constraints dynamically in order to make the whole view visible. In my case i am changing the bottonConstraint of the UITextField dynamically.
So, here goes the complete code. I have one UITextView and UITextField on UIViewController to work on for just testing...
import UIKit
class ViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {
#IBOutlet weak var textView: UITextField!
#IBOutlet weak var textField: UITextView!
/*Height Constraint for textField*/
#IBOutlet weak var bottom: NSLayoutConstraint!
var defaultHeight:CGFloat = 0.0;
override func viewDidLoad() {
super.viewDidLoad()
defaultHeight = bottom.constant;
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}
override func resignFirstResponder() -> Bool {
textView.resignFirstResponder();
textField.resignFirstResponder();
return true;
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
resignFirstResponder()
print("touched began")
}
func textViewDidEndEditing(textView: UITextView) {
resignFirstResponder()
print("text view did end editing")
}
func textViewShouldEndEditing(textView: UITextView) -> Bool {
resignFirstResponder()
print("text view should end editing")
return true;
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
print("text field should return")
resignFirstResponder()
return true;
}
func textFieldDidEndEditing(textField: UITextField) {
resignFirstResponder()
print("did end editing")
}
func keyboardWillShow(notification: NSNotification) {
print("keyboard will show.............")
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let a = keyboardSize.height;
self.bottom.constant = a + defaultHeight;
self.view.updateConstraints();
}
}
func keyboardWillHide(nofication:NSNotification)
{
print("keyboard will hide................")
bottom.constant = defaultHeight;
self.view.updateConstraints();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
when you call your UIAlertController, place condition in the completion handler if you'd like to hide the keyboard.
self.present('nameOfYourUIAlertController', animated: true, completion: {
if condition == true {
'nameOfYourUIAlertController'.textFields![0].resignFirstResponder()
}
})
This works great for me.

Resources