views:

80

answers:

2

I have several uitextfields within a view and I would like to disable the uibutton until all the fields have something entered into them. What's the best way of doing this? Ideally, I'd like to do some basic validation (make sure all entries are numbers) too.


EDIT

Couldn't get the solutions below to quite work. Below is the version that I got working (cobbled together from Brad, Mike, and various other sources)

Use the UITextFieldDelegate

Create textfields in IB, and attach to the relevant IBOutlets - textField1, textField2 etc

Create and hookup the button to its relevant IBOutlet (submitButton) and IBAction (submitAction) in IB. Uncheck enabled in IB.

Create a validate method in the view controller:

-(IBAction)validateTextFields:(id)sender
    {
        // make sure all fields are have something in them
        if ((textField1.text.length  > 0) && (textField2.text.length > 0)  && (textField3.text.length > 0)) {
            self.submitButton.enabled = YES;
        }
        else {
            self.submitButton.enabled = NO;
        }
    }

Hookup each fields 'Editing Changed' event to the validateTextFields method. (Note: The 'Value Changed' event doesn't appear to work)

Use this delegate method to limit characters (in my case to numbers, and up to one full-stop). This bit is from Erica Sadun btw.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSCharacterSet *cs;
    NSString *filtered;
    // Check for period
    if ([textField.text rangeOfString:@"."].location == NSNotFound)
    {
        cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet];
        filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
        return [string isEqualToString:filtered];
    }
    // Period is in use
    cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
    filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
    return [string isEqualToString:filtered];
}

Voila.

+3  A: 

Set yourself to be the delegate of the textfields and handle the textFieldDidEndEditing: method. In this method you can do your validation:

- (void)textFieldDidEndEditing:(UITextField *)textField {
     myButton.enabled = (myTextField1.text.length && myTextField2.length);
}
Mike Weller
thanks. my final solution added to question
cannyboy
+2  A: 

You will want to implement the UITextFieldDelegate Delegate on all of your textfields in a view cOntroller managing your view like so, making sure to validate your textfields after loading your view:

-(void) viewDidLoad {
  textField1.delegate = self;  //Note if these were created in a xib, you can do this in IB
  textField2.delegate = self;
  [self validateTextFields];
}

And Implement the textField:shouldChangeCharatersInRage: method to due the validation everytime the textfileds change:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
  [self validateTextFields];
}

Finally, do the actual validation and enable or disable your button as needed:

-(void) validateTextFields {
  if ((textField1.text.length > 0) && textField2.text.length > 0)) {
    myUIButton.enabled = YES;
  }
  else {
    myUIButton.enabled = NO;
  }
}
Brad Smith
thanks. solution added to question
cannyboy