13

I would like to enable the done button on the navbar (in a modal view) when the user writes at least a char in a uitextfield. I tried:

  • textFieldDidEndEditing: enables the button when the previous uitextfield resigns first responder (so with the zero chars in the current uitextfield).
  • textFieldShouldBeginEditing: is called when the textfield becomes the first responder. Is there another way to do this?

[EDIT]

The solution could be

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

but neither

 [self.navigationItem.rightBarButtonItem setEnabled:YES];

or

[doneButton setEnabled:YES]; //doneButton is an IBOutlet tied to my Done UIBarButtonItem in IB

work.

THelper
  • 15,333
  • 6
  • 64
  • 104
Sefran2
  • 3,578
  • 13
  • 71
  • 106

7 Answers7

32

The correct code is;

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSUInteger length = editingTextField.text.length - range.length + string.length;
    if (length > 0) {
        yourButton.enabled = YES;
    } else { 
        yourButton.enabled = NO;
    }
    return YES;
}

Edit: As correctly pointed out by MasterBeta before and David Lari later, the event should respond to Editing Changed. I'm updating the answer with David Lari's solution as this was the one marked as correct.

- (IBAction)editingChanged:(UITextField *)textField
{
   //if text field is empty, disable the button
    _myButton.enabled = textField.text.length > 0;
}
w4nderlust
  • 1,057
  • 2
  • 12
  • 22
  • Well done! Good to see you are covering the scenario where multiple characters are selected. – finneycanhelp Mar 12 '12 at 12:36
  • 1
    While this is better than the originally accepted answer, this answer is not quite right, either. If you have "clear" button turned on (see `clearButtonMode`), the `shouldChangeCharactersInRange` will not get called when you clear the field. As MasterBeta points out, you should respond to "Editing Changed" (`UIControlEventEditingChanged` if adding target programmatically). – Rob Jan 24 '14 at 15:32
  • To shorten the code, you may replace the if-else with the following: yourButton.enabled = length > 0; – Keith OYS May 14 '14 at 07:45
  • pasting the code as is in the project :-) perfect answer – Naishta Jul 06 '17 at 08:24
18

But shouldChangeCharactersInRange won't be called when user press clear button of text field control. And your button should also be disabled when text field is empty.

A IBAction can be connected with Editing Changed event of text field control. And it will be called when users type or press clear button.

- (IBAction) editDidChanged: (id) sender {
    if (((UITextField*)sender).text.length > 0) {
        [yourButton setEnabled:YES];
    } else {
        [yourButton setEnabled:NO];
    }
}
MasterBeta
  • 606
  • 6
  • 15
3

@MasterBeta: Almost correct. Follow his instructions to connect an action to Editing Changed, but this code is simpler and has no typos:

- (IBAction)editingChanged:(UITextField *)textField
{
   //if text field is empty, disable the button
    _myButton.enabled = textField.text.length > 0;

}
David Lari
  • 943
  • 11
  • 21
  • 1
    Or, perhaps even, `- (IBAction)editingChanged:(UITextField *)textField { _myButton.enabled = textField.text.length > 0; }`. – Rob Jan 24 '14 at 15:08
1

Actually, in Xcode 6.x is sufficient to flag in ON Auto-enable Return Key

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
0

This answer seems to be working in all scenarios. Single character, clear and all changes. Hope someone finds this helpful.

Community
  • 1
  • 1
Abdullah Umer
  • 4,234
  • 5
  • 36
  • 65
0

Swift 2.2

You can assign custom method "checkTextField()" to "myTextField" UITextField as:

myTextField.addTarget(self, action: #selector(self.checkTextField(_:)), forControlEvents: .EditingChanged);

and toggle the done button inside the method as:

func checkTextField(sender: UITextField) {

    doneButton.enabled = !sender.hasText();
}

No need of any delegate.

  • Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". – abarisone Jul 13 '16 at 08:47
-2

try and go with:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int lenght = editingTextField.text.length - range.length + string.length;
if (lenght > 0) {
    yourButton.enabled = YES;
} else { 
    yourButton.enabled = NO;
}
return YES;

}

This answer was marked correct when infact a better solution existed by 'w4nderlust' below. This answer is theirs, let them take the credit!

theiOSDude
  • 1,480
  • 2
  • 21
  • 36
  • It's strange... now doneButton.enabled = YES works. I also added the doneButton.enabled = NO when the text length is 0, and it works, but the button is disabilited also when the chars are two... so 0 char-button disabled, 1/3/4/5/6... chars-button enabled, 2 chars-button disabled. I don't understand why this behaviour. – Sefran2 Feb 25 '11 at 15:14
  • @fran i dont understand ", but the button is disabilited also when the chars are two... so 0 char-button disabled, 1/3/4/5/6... chars-button enabled, 2 chars-button disabled. I don't understand why this behaviour" - show me your implementation of shouldChangeCharactersInRange delegate method. – theiOSDude Feb 25 '11 at 15:19
  • - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSLog(@"%@ %d", textField.text, textField.text.length); if (textField == password) { if (textField.text.length+1 > 0) { doneButton.enabled = YES; } else { doneButton.enabled = NO; } } return YES; } – Sefran2 Feb 25 '11 at 15:50
  • a strange guess, but wouldnt "textField.text.length+1 > 0" always return yesas your instantly setting it to 1 even if it was 0 length. – theiOSDude Feb 25 '11 at 16:06
  • 1
    I resolved with: if (textField.text.length >= 0) { doneButton.enabled = YES; } if (string.length == 0 && textField.text.length == 1) { doneButton.enabled = NO; } – Sefran2 Feb 25 '11 at 16:23
  • 1
    See w4nderlust answer. It works for all cases since "NSRange" is being taken into account for multiple characters being selected. – finneycanhelp Mar 12 '12 at 12:35