6

I'm trying to get rid of the keyboard when the user touch outside my UITextField, by using this method:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [mainTextController resignFirstResponder];
    [super touchesBegan:touches withEvent:event];
}

However, this seems to call a method that is called after pressing the return button on the keyboard, but I just want the keyboard to vanish, not to press return for me. How can I accomplish that?

Thanks!

EDIT: tGilani's answer is the most straight-forward way, works like a charm, without changing to UIControl. But I guess jonkroll's answer also works.

Forge
  • 6,538
  • 6
  • 44
  • 64
Lior Pollak
  • 3,362
  • 5
  • 27
  • 48

3 Answers3

13

try

[self.view endEditing:YES];

Update:

Take a boolean value and set it to false in init method. In your textFieldShouldReturn delegate method method, execute the code if it is false, skip otherwise

- (BOOL) textFieldShouldReturn:(UITextField*)textField
{
    if (!boolean)
    {
        // YOur code logic here
    }
    boolean = false;
}

in your method where you call the endEditing method, set boolean to true.

boolean = YES;      
[self.view endEditing:YES];
bobber205
  • 12,948
  • 27
  • 74
  • 100
atastrophic
  • 3,153
  • 3
  • 31
  • 50
8

Here's how I've handled this before. First create a method on your view controller that will dismiss the keyboard by resigning first responder status on your text field:

- (IBAction)dismissKeyboard:(id)sender
{
    [mainTextController resignFirstResponder];
}

Next, in your storyboard scene for your ViewController (or nib, if you are not using storyboards) change the class of your ViewController's view property from UIView to UIControl. The view property is effectively the background behind your other UI elements. The class type needs to be changed because UIView cannot respond to touch events, but UIControl (which is a direct subclass of UIView) can respond to them.

Finally, in your ViewController's viewDidLoad: method, tell your view controller to execute your dismissKeyboard method when the view receives a UIControlEventTouchDown event.

- (void)viewDidLoad
{
    [super viewDidLoad];       
    UIControl *viewControl = (UIControl*)self.view;
    [viewControl addTarget:self action:@selector(dismissKeyboard:) forControlEvents:UIControlEventTouchDown];
}

EDIT:

Part of your concern seems to be that textFieldDidEndEditing: is called when the keyboard is dismissed. That is unavoidable, it will always be called whenever a text field loses focus (i.e. first responder status). It sounds like your problem is that you have put code to perform when the user clicks the return button in textFieldDidEndEditing:. If you do not want that code to run when the user touches outside of the text field, that is not the proper place to put it.

Instead, I would put that code in a separate method:

- (IBAction)textFieldReturn:(id)sender
{
    if ([mainTextController isFirstResponder]) {
            [mainTextController resignFirstResponder];

            // put code to run after return key pressed here...
        }
    }
}

and then call that method via Target-Action when your text field sends the control event UIControlEventEditingDidEndOnExit.

[mainTextController addTarget:self action:@selector(textFieldReturn:) forControlEvents:UIControlEventEditingDidEndOnExit];

Note that UIControlEventEditingDidEndOnExit is different than UIControlEventEditingDidEnd. The former is called when editing ends by the user touching outside the control, the latter is called when editing ends by the user pressing the return key.

Vineet Singh
  • 4,009
  • 1
  • 28
  • 39
jonkroll
  • 15,682
  • 4
  • 50
  • 43
  • It will eventually call resignFirstResponder, which is calling the method that is called after pressing the return button (I think textFieldDidEndEditing) – Lior Pollak Aug 12 '12 at 18:49
  • So I am confused - are you saying you want to dismiss the keyboard but have your text field retain first responder status? If so, that is not possible. You are correct, textFieldDidEndEditing will be called no matter what when keyboard is dismissed and the text field loses focus. Instead of putting your return button logic there, look into using a target-action for control event UIControlEventEditingDidEndOnExit. This way you can distinguish between user hitting the return button on keyboard while editing the text field vs user leaving the text field by clicking elsewhere in view. – jonkroll Aug 12 '12 at 19:06
  • I didn't fully understand you. Can you edit your answer to show what you meant? Thanks – Lior Pollak Aug 12 '12 at 19:14
0

You need to change your ViewController's view property from UIView to UIControl using the Identity Inspector:

From there, you simply create an IBAction and tell the textfield to dismiss (which I am assuming is your mainTextController). If mainTextController is not the textfield you want the keyboard to dismiss on then change the resignFirstReaponder method to your textfield like so.

- (IBAction)backgroundTap:(id)sender {
[myTextField resignFirstResponder];
}

then from there go back into your View Contoller's .xib file and connect the action to the Control View and select "Touch Down".

Vineet Singh
  • 4,009
  • 1
  • 28
  • 39
Zack
  • 871
  • 10
  • 24