Question

I have a simple UIViewController that contains some UITextField. The navigation bar at the top has a UIBarButtonItem (created in Storyboard) which is called Save which ultimately allows the user to save the entry they are typing in and therefore dismiss this UIViewController.

I want to enforce that the user has to at least enter in 2 or 3 text fields before the Save button becomes selectable, so it's there, but greyed out till the user fills in two specified text fields.

How would I achieve something like this?

I'm sorry for the small question, but there really isn't much more to it than this; grey out the BarButtonItem till the fields have been filled in and then allow the user to click on it. I've searched online and very surprisingly cannot find much information on this.

Any guidance would be really appreciated.

Update. I have tried adding:

self.navigationItem.rightBarButtonItem.enabled = NO; to the viewDidLoad and viewWillAppear just to see if I can start disabling my bar button items and it doesn't get disabled at all.

Was it helpful?

Solution

Everything created with Storyboards.

First of all you need IBAction and IBOutlet for your UIBarButton. You can do that in your .m

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIBarButtonItem *myBarButtonItem;
@end

And:

- (IBAction)myBarButtonItemAction:(id)sender
{
    // your code
}

I'll suppose that you have 2 UITextField created with Xcode Interface Builder, then add them as IBOutlet to your .m:

@property (strong, nonatomic) IBOutlet UITextField *myTextFieldOne;
@property (strong, nonatomic) IBOutlet UITextField *myTextFieldTwo;

Add this line to viewDidLoad to disable the UIBarButton:

self.myBarButtonItem.enabled = FALSE;

To take control of your UITextField you can do it in two ways:

First one with UITextFieldDelegate, add this code to .m

@interface ViewController () <UITextFieldDelegate>

You can check UITextFieldDelegate Protocol Reference here.

And the delegate method you need is one of this two, depending on what do you want to achieve:

– textFieldDidBeginEditing:
– textFieldDidEndEditing:

However I don't like this approach, because with textFieldDidBeginEditing: someone can begin the edit and never enter text. With textFieldDidEndEditing: you need to call something to dismiss the Keyboard: [self.myTextFieldOne resignFirstResponder]. Also you can/should implement another UITextFieldDelegate who take's control of the 'Return' key – textFieldShouldReturn:

If you decide to use the UITextFieldDelegate remember to add:

self.myTextFieldOne.delegate = self;
self.myTextFieldTwo.delegate = self;

Then, my second option is to add this line of code to viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkTextFields) name:UITextFieldTextDidChangeNotification object:nil];

Here you receive a notification to your SEL every time the text is changed into a UITextField

then:

- (void) checkTextFields
{
    // Add here your logic to check TextFields and decide if they have text
    if ([self.myTextFieldOne.text length] != 0 && [self.myTextFieldTwo.text length] != 0)
    {
        self.myBarButtonItem.enabled = TRUE;
    }
    else
    {
        self.myBarButtonItem.enabled = FALSE;
    }
}

You can check a small demo with my second option here.

OTHER TIPS

You can achieve the same by one of the methods

  1. In ViewDidLoad() method disable the UIBarbutton
  2. Delegate method of UITextField check for the condition. You can achieve this by having an variable declared and subsequently incrementing the count in UITextFielddelegate 'textFieldShouldReturn' method.
  3. Once condition is satisfied enable the save UIBarButton.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top