29

I have a UIView with multiple text boxes. Now i have used delegates to change the responder from from text field to another. In this case my key board goes away when the user comes to last text field.

but now i want to hide my key board when the user touches UIView(touches any where on screen apart from text boxes). Can some one help me with this.

Thanks

nbojja
  • 1,665
  • 7
  • 28
  • 38

11 Answers11

43

Use resignFirstResponder in touchesBegan, like so:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];
    if(touch.phase == UITouchPhaseBegan) {
        [self.myTextField resignFirstResponder];
    }
}

You may need to call this on multiple text fields if you're not sure where the focus is currently located; I haven't tested that case.

Additionally, in Interface Builder, you'll need to enable the "User Interaction Enabled" checkbox for the view, or programatically use:

myView.userInteractionEnabled = YES;
PCheese
  • 3,231
  • 28
  • 18
  • But where to call this resignFirstResponder. How to know the user touched the UIView??? – nbojja Jun 08 '09 at 06:09
  • 1
    I've edited the post to include an example within touchesBegan. – PCheese Jun 08 '09 at 06:37
  • Hey..Thanks for your help..it worked well with UIView. But i have another scenario where i have text boxes in UITableView. in this case your code is not working. I am very new to iPhone development, so please...... – nbojja Jun 08 '09 at 07:13
  • If you want to find out which control to call resignFirstResponder on, you can use isFirstResponder. So in my code i call "if ([myTextField isFirstResponder]) [myTextField resignFirstResponder]; else if...". One could probably be more systematic and iterate through the subviews, look for views/controls that are UIResponder and do the same check as above. – pschang Oct 16 '10 at 16:58
  • thaaaaaaannnnnnk you :) comment: it doesn't work with UIScrollViews – cV2 Jan 10 '12 at 14:42
  • Or you can call [UIApplication.sharedApplication sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil]; if you don't know which textField is first responder – Bejil Apr 01 '19 at 15:56
26

Just call this in your view controller when you want to hide the keyboard.

[self.view endEditing:NO];

charliehorse55
  • 1,940
  • 5
  • 24
  • 38
14

I use

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     UITouch *touch = [touches anyObject];
     if(touch.phase==UITouchPhaseBegan){
         //find first response view
         for (UIView *view in [self.view subviews]) {
             if ([view isFirstResponder]) {
                 [view resignFirstResponder];
                 break;
             }
         }
     }
}
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
3

A super easy way to do this is working on what PCheese said.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
    [self.view endEditing:YES];
}

}

I previously used [self.view endEditing:YES]; for a button event, but when combined with the previous answer it works a treat. Much easier, and you don't have to do anything else - just put it in your .m file. Also, this works with all (at least, as far as I have seen) text fields (works for UITextField and UITextView).

I know OP probably won't still need this but I just want to share it for others with the same problem.

user1785715
  • 180
  • 1
  • 1
  • 8
3

According to Beginning iPhone Development, you draw a round rect button so that it covers your entire UI; the complete screen. Then go to the Layout menu and click Send to Back. Then in the inspector, change the button's type from round rect to Custom. Now add a touch up inside event to this button and attach it to a method which handles it. Within the body of this method, make sure you have the statements:

[myTextFieldOne resignFirstResponder];
[myTextFieldTwo resignFirstResponder];

Basically send the resignFirstResponder message to each of your text fields, or any field that can produce a keyboard.

I'm actually really new to the iPhone SDK. I don't know if this is the best method, but it works and it's what I learned from the aforementioned book. Hope it helps.

Jorge Israel Peña
  • 36,800
  • 16
  • 93
  • 123
2

Thanks Blaenk, I was trying to work out how to do this and didn't realise I could put a button in the background, nice trick! Here's my contribution (new to this site and to Cocoa Touch so it may not be the most robust code ever, but it's working so far...):

I call this method from the touchUpInside event on my UIButton:

-(void)closeKeyboard:(id)sender {
    UIView *theFirstResponder = [self findFirstResponder];
    if (theFirstResponder) {
        [theFirstResponder resignFirstResponder];
    }
}

Where this loop finds the firstResponder:

- (UIView *)findFirstResponder {  
    UIView *firstResponderView = nil;
    for (UIView *view in [self entryFields]) {  
        if ([view isFirstResponder]) {  
            firstResponderView = view;
            break;
        }
    }   
    return firstResponderView;  
}

It is dependent on each of the UITextField controls in the view having a tag assigned to them (again, can do that in Interface Builder).

My two cents anyway, though i'd better give something back!

Paul J
  • 799
  • 1
  • 6
  • 16
2

it work for me

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

only need into self.view have an UItextField

http://objdev.com/2013/11/Dismissing-iOS-Keyboard-Self-View-EndEditing

user237474
  • 21
  • 2
2

SO I agonized over this and I figured it out..

you don't need the other button or anything.

All you need to do is select "Files owner", in the inspector drag from its textField outlet (or whatever you named it) to your actual textfield (via whatever you named it) This will be in addition to whatever inputs you already had wired up.

and ofcourse in addition to the Control outlet (UIview changed to UIControl via inspector) to files owner via backgroundtouched...the first thing we all tried

antizyx
  • 21
  • 1
1

The most appropriate way of solving this problem is using the following method:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    if(![touch.view isMemberOfClass:[UITextField class]]) {
        [touch.view endEditing:YES];
    }
}

Note: This does not work on UIScrollView instances.

ArtSabintsev
  • 5,170
  • 10
  • 41
  • 71
1

Change the class UIView to class UIControl from the identify tab of inspector. Add this:

- (IBAction)tabBackground:(id) sender;

to your .h file.

Add this to your .m file:

- (IBAction)tabBackgroup:(id) sender {
    [nameField resignFirstRespnder];
    [numberField resignFirstResponder];
}

Connect your tabBackground from the inspector, action received section to the UIView (which is an an UIControl) and you're good to go.

EDUsta
  • 1,932
  • 2
  • 21
  • 30
jawed
  • 41
  • 1
0

For swift 4.0

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch = touches.first
    if touch?.phase == UITouchPhase.began {
        touch?.view?.endEditing(true)
    }
}
Tanvir Singh
  • 131
  • 1
  • 2