How to dismiss keyboard when user tap other area outside textfield?

IosObjective C

Ios Problem Overview


today I tried to run my code on my iPod (iOS 6.1.3) and I found something interesting here...

first, when I tap on textfield the keyboard shows up but it won't hide when I tap somewhere else outside textfield.

so I decided to Googling and found this solution :

_fieldEmail.delegate = self;
_fieldEmail.returnKeyType = UIReturnKeyDone;

_fieldPassword.delegate = self;
_fieldPassword.returnKeyType = UIReturnKeyDone;

_fieldRegisterName.delegate = self;
_fieldRegisterName.returnKeyType = UIReturnKeyDone;

_fieldRegisterEmail.delegate = self;
_fieldRegisterEmail.returnKeyType = UIReturnKeyDone;

_fieldRegisterPassword.delegate = self;
_fieldRegisterPassword.returnKeyType = UIReturnKeyDone;

it works... it gives a 'DONE' button on the bottom of keyboard and now the keyboard can be hidden by pressing it.

but I have 2 problems here :

  1. the keyboard only hide when 'DONE' button is tapped. not by tapping other area outside text field. I don't know if this normal on iOS world, but usually I see lot of apps don't act like this.
  2. is there any way to loop this process so I don't have manually add that delegate one by one of all textfield that I have? how to do that?

that's all I need to know

Ios Solutions


Solution 1 - Ios

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

OR

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];    
}

Solution 2 - Ios

  1. Simply add an UITapGestureRecogniser to your view that will lead to calling resignFirstResponder

In viewDidLoad :

UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] 
                                   initWithTarget:self
                                   action:@selector(hideKeyBoard)];

[self.view addGestureRecognizer:tapGesture];

And then :

-(void)hideKeyBoard {
       [yourTextField resignFirstResponder];
}

2.You could subclass UITextField but unless you have 1000 textFields it is ok to do like you currently do.

Solution 3 - Ios

This is regards to Swift programming for Xcode 6.0.1

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
        
    let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleSingleTap:")
    tapRecognizer.numberOfTapsRequired = 1
    self.view.addGestureRecognizer(tapRecognizer)
}

func handleSingleTap(recognizer: UITapGestureRecognizer) {
    self.view.endEditing(true)
}

Solution 4 - Ios

Use Either

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];

and code of method

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [self.TextFiledName resignFirstResponder];

}

OR _ And The best Other option is

Just add

  [self.view endEditing:YES];

And key board will hide when you tapped anywhere from view:)

Solution 5 - Ios

Dismissing the keyboard

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
        [self.view endEditing:YES];
        [super touchesBegan:touches withEvent:event];
    }

Solution 6 - Ios

Simple,

Use IQKeyboardManager and put this line of code in AppDelegate.m

[[IQKeyboardManager sharedManager] setShouldResignOnTouchOutside:YES];

Solution 7 - Ios

What I usually do is call

[field resignFirstResponder]; 

from an invisible button over the view. I'm sure theres a nicer way to do it. It's been a while since I've done this in an app.

Solution 8 - Ios

Here's how I do it:

In the myView's .h file:

@property (strong) UITextField * savedTextField;

In the myView's .m file:

@implementation myView

@synthesize savedTextField;

In the myView's init routine:

[self setSavedTextField: nil];

In the myView's textField delegate area I save the id of whichever textField is currently activating:

- (BOOL) textFieldShouldBeginEditing: (UITextField *) textField
   {
   [self setSavedTextField: textField];
   .
   .
   .
   return( YES );
   }

And in the myView's routine that routes all the traffic for the other controls when they are accessed, I have code that looks to see if a textField was active and, if one was, it calls on it to resign its FirstResponder status and then drops a nil into the savedTextField property:

- (void) handleCtrlEvents: (UIControl *) aCtrl
  {
  if ( [self savedTextField] != nil )
     {
     [[self savedTextField] resignFirstResponder];
     [self setSavedTextField: nil];
     }
  .
  .
  .
  }

This works cleanly for me.

Solution 9 - Ios

I ran into the exact same problem. Usually what you want is, that wherever you click inside your App (which is displayed in your main / current UIView) but not on the keyboard to close it. After searching the web for a smart solution and testing several, I think it is the best to extend/subclass/implement the UIGestureRecognizerDelegate

Since many controls such as UITableView etc. can respond to gestures (select, scrolling etc.) and if you simply add a UITapGestureRecognizer to the whole (main-)ViewController's view to close the keyboard, the user experience is not the best, since the user needs to tap twice if he didn't intend to close the keyboard but e.g. select a row from a UITableView inside the App's current "main" View.

Since I am quite new to the whole iOS and swift thing and swift code examples are rare, here's my full keyboard control snipped:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

override func viewDidLoad(){
     self.initializeCloseKeyboardTap()
}

func initializeCloseKeyboardTap() {
    
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardOpen:", name: UIKeyboardDidShowNotification, object: nil)
    
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardClose:", name: UIKeyboardDidHideNotification, object: nil)
    let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleOnTapAnywhereButKeyboard:")
    tapRecognizer.delegate = self //delegate event notifications to this class
    self.view.addGestureRecognizer(tapRecognizer)
    
}


func onKeyboardClose(notification: NSNotification) {
    println("keyboardClosed")
}

func onKeyboardOpen(notification: NSNotification) {
    println("keyboardOpen")
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    self.view.endEditing(true)
    return false
}

you can nest it inside the ViewController and call initiallizeCloseKeyboardTa() in viewDidLoad implementation... It also implements a norfication observer to receive events as soon as the keyboard (finished to be) opened or closed via NSNotificationCenter UIKeyboardDidShowNotification and UIKeyboardDidHideNotification

Hope that save's other people some time :-)

Solution 10 - Ios

|*| Dismissing the UITextField’s Keyboard : override the method touchesBegan:withEvent: for the ViewController

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    view.endEditing(true)
    super.touchesBegan(touches, withEvent: event)
}

|OR|

override func viewDidLoad()
{
    super.viewDidLoad()
// For tapping outside text box
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}

// For tapping outside text box
func DismisKeyPadFnc()
{
    view.endEditing(true)
}

|*| Dismissing the UITextField’s Keyboard on induvidual textbox :

class NamVcc: UIViewController, UITextFieldDelegate
{
    @IBOutlet var NamTxtBoxVid: UITextField!
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
    
    // For hitting return key
        NamTxtBoxVid.delegate = self
        
    // For tapping outside text box
        self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
    }
    
/* For hitting return key */
    func textFieldShouldReturn(NamTxtBoxPsgVid: UITextField) -> Bool
    {
        NamTxtBoxPsgVid.resignFirstResponder()
        return true
    }
    
/* For tapping outside text box */
    func DismisKeyPadFnc()
    {
        view.endEditing(true)
    }
}


|*| Implementing Next button Click :

  1. You will be needing to set the tags in the incremental sequence of the textfields in xib/Storyboard or in code.

  2. Set the delegate for each of the textfields.

  3. Then paste the following code in your view controller to have the desired effect:

    func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool { let NxtTxtBoxTagVal : Int = TxtBoxPsgVar.tag + 1

     let NxtTxtBoxVal: UIResponder? = TxtBoxPsgVar.superview?.superview?.viewWithTag(NxtTxtBoxTagVal)
     
     if let TxtBoxVal = NxtTxtBoxVal
     {
         // Found next responder, so set it.
         TxtBoxVal.becomeFirstResponder()
     }
     else
     {
         // Not found, so remove keyboard.
         TxtBoxPsgVar.resignFirstResponder()
     }
     return true
    

    }

Solution 11 - Ios

I prefer IQKeyboardManager. You can simply handle keyboard in any state. To active IQKeyboard just add one line in AppDelegate and to dismiss keyboard on outside touch add code as below,

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  IQKeyboardManager.shared.enable = true
  IQKeyboardManager.shared.shouldResignOnTouchOutside = true

  return true
}

Solution 12 - Ios

I think

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

is convenient but not the best solution. and the TapGestureRecongnizer is better but hard to use,you have to set delegates and add and remove the Recongnizer. So I wrote a simple subclass which can be easily used:

class TapHideTextField: UITextField {
override func awakeFromNib() {
    super.awakeFromNib()
    tapGr = UITapGestureRecognizer(target: self, action:"tap")
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "didBeginEditing", name:UITextFieldTextDidBeginEditingNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "didEndEditing", name:UITextFieldTextDidEndEditingNotification, object: nil)
    
}

deinit{
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

var tapGr:UITapGestureRecognizer!
func tap(){
    self.endEditing(true)
}

func didBeginEditing(){
    self.superview!.addGestureRecognizer(tapGr)
}


func didEndEditing(){
    self.superview!.removeGestureRecognizer(tapGr)
}

}

you should concern about the superview and the cancelTouchesInView property.

or in GitHub:https://github.com/lilidan/TapHideText/blob/master/TapHideTextField.swift

Solution 13 - Ios

If you're using scroll view (or table view) controller, add these lines there:

    override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        view.endEditing(true)
    }

Solution 14 - Ios

-(void) textFieldDidBeginEditing: (UITextField *) textField{
     [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(DismissKeyboard:)]];
}

-(void) DismissKeyboard:(UITapGestureRecognizer *) sender{
    [self.view endEditing:YES];
    [self.view removeGestureRecognizer:sender];
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSaint RobsonView Question on Stackoverflow
Solution 1 - IosicodebusterView Answer on Stackoverflow
Solution 2 - IosLudoZikView Answer on Stackoverflow
Solution 3 - IosVinod JoshiView Answer on Stackoverflow
Solution 4 - IosiPatelView Answer on Stackoverflow
Solution 5 - IosMohammad Kamran UsmaniView Answer on Stackoverflow
Solution 6 - IosSandip Patel - SMView Answer on Stackoverflow
Solution 7 - IosSam JarmanView Answer on Stackoverflow
Solution 8 - IosGallymonView Answer on Stackoverflow
Solution 9 - IosFrithjof SchaeferView Answer on Stackoverflow
Solution 10 - IosSujay U NView Answer on Stackoverflow
Solution 11 - IosKomal GoyaniView Answer on Stackoverflow
Solution 12 - Ioscy SGView Answer on Stackoverflow
Solution 13 - IosDisplay NameView Answer on Stackoverflow
Solution 14 - Iosjaya rajView Answer on Stackoverflow