3

I am trying to implement search bar in one of my page.

I am not using regular search bar due to its design.

What I have is as below.

UIImageView above UIView (textfield background)
UITextField above UIImageView (textfield)

I am using delegates for UITextField.

In code I have searchTF.clearButtonMode = UITextFieldViewModeWhileEditing; to show the clear button.

Search is working fine but the problem is in delegate of clear button.

I have below code

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    if (textField == searchTF) {

        NSLog(@"clicked clear button");
        [textField resignFirstResponder]; // this is not working
        // also below is not working
        // [searchTF resignFirstResponder];
    }

    return YES;
}

When I click clear button, I get NSLog of text "clicked clear button", however the keyboard doesn't get dismissed.

Any idea why keyboard is not getting dismissed when I have


Edit 1

Even I tried as below using [self.view endEditing:YES];, but still its not working.

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    if (textField == searchTF) {
        [self.view endEditing:YES];
        [self hideAllKeyboards];
    }
    return YES;
}
braX
  • 11,506
  • 5
  • 20
  • 33
Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276

3 Answers3

5

Additional to my comment I made some testing and here are my results:

I've just implemented a UITextField with all delegate methods like this:

- (BOOL)textFieldShouldClear:(UITextField *)textField {
  NSLog(@"Should Clear");
  [textField resignFirstResponder];
  return YES;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
  NSLog(@"Begin editing");
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
  NSLog(@"End editing");
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
  NSLog(@"Should begin editing");
  return YES;
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
  NSLog(@"Should end editing");
  return YES;
}

- (BOOL)textField:(UITextField *)textField
    shouldChangeCharactersInRange:(NSRange)range
                replacementString:(NSString *)string {
  NSLog(@"Change char");
  return YES;
}

As soon as you hit the clear button the log outputs:

2014-07-26 11:08:44.558 Test[36330:60b] Should Clear
2014-07-26 11:08:44.558 Test[36330:60b] Should end editing
2014-07-26 11:08:44.559 Test[36330:60b] End editing
2014-07-26 11:08:44.560 Test[36330:60b] Should begin editing
2014-07-26 11:08:44.561 Test[36330:60b] Begin editing

As you can see the shouldBeginEditingand the didBeginEditing methods get called after clearing so the resignFirstResponder in textFieldshouldClear gets called just before a new becomeFirstResponder is called by shouldBeginEditing or didBeginEditing.

Jonathan
  • 6,507
  • 5
  • 37
  • 47
dibi
  • 3,257
  • 4
  • 24
  • 31
  • 1
    +1 : for detail explanation... Now I understand what was going... thanks for making it clear... – Fahim Parkar Jul 26 '14 at 09:59
  • 2
    Mh I think the way you solved the problem is more a workaround because it could be that your timer is quicker than the delegate methods e.g. on slower devices. A better solution would be to implement `textFieldShouldClear` like this `[textField resignFirstResponder];` `textField.text = @"";` `return NO;` – dibi Jul 26 '14 at 10:03
  • In `textFieldShouldClear`, `[textField resignFirstResponder];`. That was BIG problem.. that's why I went with `NSTimer` – Fahim Parkar Jul 26 '14 at 10:36
  • 1
    @FahimParkar yeah but you did not return a `NO`, that's the difference! Look closely at my comment – dibi Jul 26 '14 at 10:37
0

I am not sure what was the problem, but I solved calling the dismiss keyboard method after some interval using NSTimer.

Below is what I did.

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    if (textField == searchTF) {
        [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(hideAllKeyboards) userInfo:nil repeats:NO];
    }
    return YES;
}

-(void) hideAllKeyboards {
    [searchTF resignFirstResponder];
}

This way, after clicking the clear button, keyboard is getting dismissed.

It would be great if someone post answer as why this is happening. I will mark that answer as accepted.


Edit 1

As per Daniel answer, I did below.

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    if (textField == searchTF) {
        isFilterOn.text = @"no";
        [textField resignFirstResponder];
        textField.text = @"";
        [self myTextFieldDidChange];
    }

    return NO;
}

In myTextFieldDidChange, I am showing the filtered list and un-filtered list based on the text I have in UITextField.

Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276
  • 2
    I think this is because the `textFieldShouldClear` -method does invoke a call of `textFieldDidBeginEditing` because a clear is also an edit. Therefor the `textFieldDidBeginEditing` is firing a `becomeFirstResponder` and the keyboard doesn't get dismissed. You could test this out by implementing all delegate methods of `UITextField` and set some breakpoints. – dibi Jul 26 '14 at 08:59
  • 1
    simply use [self.view endEditing:YES] that hide your keyBoard – Nitin Gohel Jul 26 '14 at 09:14
  • @NitinGohel : Already did, still not working... I have already updated question for the same... Check Daniel answer for the reason... – Fahim Parkar Jul 26 '14 at 09:58
0

I believe your textfield IBOutlet is properly connected ,Although you can try

[[[UIApplication sharedApplication] keyWindow] endEditing:YES];

Hemant Chittora
  • 3,152
  • 3
  • 19
  • 25