NSAlert Input Box, Validating NSTextField - objective-c

I've run into a couple of topics that discuss an input box using NSAlert like the following.
- (NSString *)input: (NSString *)prompt defaultValue: (NSString *)defaultValue {
NSAlert *alert = [NSAlert alertWithMessageText: prompt
defaultButton:#"OK"
alternateButton:#"Cancel"
otherButton:nil
informativeTextWithFormat:#""];
NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
[input setStringValue:defaultValue];
[alert setAccessoryView:input];
NSInteger button = [alert runModal];
if (button == NSAlertDefaultReturn) {
[input validateEditing];
return [input stringValue];
} else if (button == NSAlertAlternateReturn) {
return nil;
} else {
return nil;
}
}
So you can insert a textbox just like you do with AlertView in iOS. But how can you validate the text field value to enable and disable the default button? iOS has (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView to let you validate the input.
Thank you.

set
input.delegate=self;
and then implement the following methods
(void)controlTextDidChange:(NSNotification *)notification
(void)controlTextDidEndEditing:(NSNotification *)notification
you can validate here

Related

Add "informative text" to Alert if TextFields are empty

I am trying to code a NSAlert, that appears when when some NSTextFields are empty.
I have 3 NSTextFields and I would like to have a NSAlert that shows which TextField ist empty in a list. It´s possible for me to do it for one text field, but how can I code it that the empty NSTextFields appear in the Alert ? If one Textfield is empty in the Altert should stand "TextField 1 is empty". If Field 1 and 2 are empty there should stand "TextField 1 is empty" and in the second row "TextField 2 is empty".
Here is my code:
if ([[TextField1 stringValue] length] == 0) {
NSAlert* alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"OK"];
[alert setMessageText:#"Error"];
[alert setInformativeText:#"TextField 1 is empty"];
[alert beginSheetModalForWindow:[self.view window] completionHandler:^(NSInteger result) {
NSLog(#"Success");
}];
}
You can get the information automatically by a notification.
Assign the tags 1, 2, 3 to the text fields.
Set the delegate of all text fields in Interface Builder to the class you want to display the alert in.
implement this method
- (void)controlTextDidChange:(NSNotification *)aNotification
{
NSTextField *field = [aNotification object];
if ([[field stringValue] length] == 0) {
NSInteger tag = field.tag;
NSAlert* alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"OK"];
[alert setMessageText:#"Error"];
[alert setInformativeText:[NSString stringWithFormat:#"TextField %ld is empty", tag]];
[alert beginSheetModalForWindow:[self.view window] completionHandler:^(NSInteger result) {NSLog(#"Success");}];
}
}
I would chain the if-statements to get the desired result.
Set up a empty string and check every textField one after another. Add the error line to the string if it is empty. Don't forget to add a line break after appending a string.
My words in code:
NSString* errorMessage = #"";
if ([[TextField1 stringValue] length] == 0) {
errorMessage = #"TextField 1 is empty.\n";
}
if ([[TextField2 stringValue] length] == 0) {
errorMessage = [errorMessage stringByAppendingString:#"TextField 2 is empty.\n"];
}
if ([[TextField3 stringValue] length] == 0) {
errorMessage = [errorMessage stringByAppendingString:#"TextField 3 is empty."];
}
if (![errorMessage isEqualToString:#""]) {
NSAlert* alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"OK"];
[alert setMessageText:#"Error"];
[alert setInformativeText:errorMessage];
[alert beginSheetModalForWindow:[self.view window] completionHandler:^(NSInteger result) {
NSLog(#"Success");
}];
}
This way you get dynamic output depending on which NSTextField was empty.

The UIButton not responding as it should in single-view app in iOS6

The selector 'go' with IBAction return type is not responding correctly. If the button is clicked with the text field being empty i.e its value being nil , the flow should return the 'if' part and not 'else'. But it works fine when I click the button second time. what can be the problem ?
Below is the code from implementation file i.e. ViewController.m where I have implemented the go selector.
#synthesize textField = _textField;
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
//Clear the text field
self.textField.text =nil;
}
NSString *s;
-(IBAction)go:(id)sender
{
[self.textField resignFirstResponder];
if (self.textField.text == nil)
{
s = [NSString stringWithFormat:#" Enter Your Name First " ];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Blank Field : "
message:s
delegate:self
cancelButtonTitle:#"OKAY"
otherButtonTitles:nil];
[alert show];
}
else
{
s = [NSString stringWithFormat:#"Hello %# " , self.textField.text];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello "
message:s
delegate:self
cancelButtonTitle:#"Thanks"
otherButtonTitles:nil];
[alert show];
}
}
Please help.
Thanks in advance.
Instead of using nil as your comparator I would instead use something more concrete like
if ([self.textfield.text length] > 0)
{
}
else
{
}

How to check the return value of UIAlertView?

I want to check if the user click "yes" for example I want to put a certain action.
This is my line of code:
UIAlertView* mes=[[UIAlertView alloc] initWithTitle:#"Are you sure?" message:#"this will start a new game" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[mes show];
So I want to say if user tap "yes" preform this action
this is my method: I want to say if the user click "yes" create the new game.
- (IBAction)newGame:(UIButton *)sender {
UIAlertView* mes=[[UIAlertView alloc] initWithTitle:#"Are you sure?" message:#"this will start a new game" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[mes show];
self.flipsCount = 0;
self.game = nil;
for (UIButton *button in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:button]];
card.unplayble = NO;
card.faceUp = NO;
button.alpha = 1;
}
self.notificationLabel.text = nil;
[self updateUI];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex])
{
//User clicked ok
NSLog(#"ok");
[self newGame:[UIButton alloc] ];
}
else
{
//User clicked cancel
NSLog(#"cancel");
}
}
it takes ButtonIndex values from left to right .
Insert the following method in the same class (or in the class you have set as delegate):
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
//User clicked ok
}
else
{
//User clicked cancel
}
}
Use the delegate method of UIAlertView as
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)//Yes
{
self.flipsCount = 0;
self.game = nil;
for (UIButton *button in self.cardButtons)
{
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:button]];
card.unplayble = NO;
card.faceUp = NO;
button.alpha = 1;
}
self.notificationLabel.text = nil;
[self updateUI];
}
else//No
{
//do something
}
}

Passing NSComboBox value that is inside a NSAlert Sheet

I have a NSAlert Sheet that has a NSComboBox inside. How can i pass the combo box value when the user has pressed a button of the NSAlert?
code:
NSComboBox* comboBox = [[NSComboBox alloc] initWithFrame:NSMakeRect(0, 0, 150, 26)];
[comboBox setTitleWithMnemonic:#"2"];
for (int i=2; i<[array count]+1; i++){
[comboBox addItemWithObjectValue:[NSString stringWithFormat:#"%i", i]];
}
[comboBox setEditable:NO];
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:#"Okay"];
[alert addButtonWithTitle:#"Cancel"];
[alert setMessageText:#"Choose a number"];
[alert setAccessoryView:comboBox];
[alert beginSheetModalForWindow:_window modalDelegate:self didEndSelector:#selector(alertToChooseX:returnCode:contextInfo:) contextInfo:nil];
- (void)alertToChooseX:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if (returnCode == NSAlertFirstButtonReturn) {
NSLog(#"Pressed Okay");
}
}
Describe comboBox in Your header file and after pushed button "Okay" take it's value like this:
in .h
NSComboBox *comboBox;
in .m
comboBox = [[NSComboBox alloc] initWithFrame:NSMakeRect(0, 0, 150, 26)];
[comboBox setTitleWithMnemonic:#"2"];
.... // Your all code goes here
- (void)alertToChooseX:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if (returnCode == NSAlertFirstButtonReturn) {
NSLog(#"Pressed Okay");
NSLog(#"Selected ComboBox's String Value: %#", [comboBox stringValue]);
NSLog(#"Selected ComboBox's Object Value: %#", [comboBox objectValueOfSelectedItem]);
NSLog(#"Selected ComboBox's Item Index: %ld", [comboBox indexOfSelectedItem]);
}
}
Note: Don't forget to release comboBox because it's allocating memory.

Keep UIAlertView displayed

I have a UIAlertView with a textField on it and two buttons: Save & Cancel. When the Save button is tapped I am checking if the text field isn't empty and after if it is I simply want to change the textFields placeholder to: #"enter a name please" and KEEP the alert view on screen. However it is automatically dismissed.
How do I override that?
Add a target to the textfield in a subclassed alertView. You can subclass the alertView and not dismiss as described in this post
[[alertView textFieldAtIndex:0] addTarget:self action:#selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged];
Then write a function called textFieldDidChange that checks the current textfield of your alertView and set a boolean value so you know whether or not to dismiss the alert.
- (void) textFieldDidChange
{
NSString *alertViewText = [[alertView textFieldAtIndex:0] text];
if ([alertViewText isEqualToString:#""]) {
[alertView setMessage:#"Enter a name please."];
} else {
[alertView setMessage:#"Default Message"];
}
}
* Alternatively, I would suggest disabling "Save" when it is empty and not have to subclass. *
- (void) textFieldDidChange
{
NSString *alertViewText = [[alertView textFieldAtIndex:0] text];
if ([alertViewText isEqualToString:#""]) {
[alertView setMessage:#"Enter a name please."];
for (UIViewController *view in alertView.subview) {
if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
if ([[[button titleLabel] text] isEqualToString:#"Save"])
[button setEnabled:NO];
}
}
} else {
[alertView setMessage:#"Default Message"];
for (UIViewController *view in alertView.subview) {
if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
if ([[[button titleLabel] text] isEqualToString:#"Save"])
[button setEnabled:YES];
}
}
}
}