Add "informative text" to Alert if TextFields are empty - objective-c

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.

Related

NSAlert beginSheetModalForWindow does not display alert

I have the following code in a ViewController in my OS X app:
NSAlert *alert = [NSAlert new];
alert.messageText = #"Connection error";
alert.informativeText = #"You do not appear to be connected to the internet";
[alert addButtonWithTitle:#"Third button"];
[alert addButtonWithTitle:#"Second button"];
[alert addButtonWithTitle:#"Ok"];
[alert beginSheetModalForWindow:[[self view] window] completionHandler:^(NSInteger result) {
NSLog(#"Success");
}];
// [alert runModal];
When this code executes nothing happens. If I comment out the beginSheetModalForWindow line, and uncomment [alert runModal], then the alert is displayed as expected.
What am I doing wrong here that it doesn't display as a sheet?
I imagine you are trying to show the NSAlert too early (while the window is setting up) try adding a perfromselector with a delay to see if this is the case
[self performSelector:#selector(delayed) withObject:nil afterDelay:1.0];
-(void)delayed {
NSAlert *alert = [NSAlert new];
alert.messageText = #"Connection error";
alert.informativeText = #"You do not appear to be connected to the internet";
[alert addButtonWithTitle:#"Third button"];
[alert addButtonWithTitle:#"Second button"];
[alert addButtonWithTitle:#"Ok"];
[alert beginSheetModalForWindow:[self.view window] completionHandler:^(NSInteger result) {
NSLog(#"Success");
}];
}
If so, try showing it once the window has loaded, for example in
- (void)windowDidLoad {
//code here
}

Two UiAlertView messages with different button actions

I have been successfully created two alerts with four buttons. The first AlertView works great but the second alertView crashes my up. Here is my code:
-(void)showAlertWithTextField{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"info" message:#"Set Time For The Game." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"cancel", nil];
[alertView setTag:101];
alertView.alertViewStyle=UIAlertViewStylePlainTextInput;
[[alertView textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeNumberPad];
[[alertView textFieldAtIndex:0] becomeFirstResponder];
[alertView show];
}
-(void)showexitAlertView
{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"Timeout" message:[NSString stringWithFormat:#"Your final score is: %i", runningSore] delegate:self cancelButtonTitle:#"Restart" otherButtonTitles:#"Exit", nil];
[alertView setTag:102];
[alertView show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
UITextField *field = [alertView textFieldAtIndex:0];
setTime = [field.text intValue];
NSLog(#"%d", setTime);
if (alertView.tag == 101 && buttonIndex == 0) {
//if (buttonIndex == 0){
NSLog(#"Ok");
[self setTimer];
[self countDownTimerPrepare];
[self countDownTimerIntro];
[self prepareForIntroAnimation];
[self performIntroAnimation];
[self categoriesList];
}
else if (buttonIndex == 1){
NSLog(#"Cancel");
ChooseViewController * controller = [[ChooseViewController alloc] initWithNibName:#"ChooseViewController" bundle:nil];
//controller.countdownLabel.text= score;
[self presentViewController:controller animated:YES completion:nil];
}
else if (alertView.tag==102 && buttonIndex == 0){
NSLog(#"Restart");
}
else if (buttonIndex == 1){
NSLog(#"Exit");
}
}
Here is the drbugging message when i press a button from the second Alert view:
2013-09-11 17:12:06.106 Diplomatiki[2808:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'textFieldIndex (0) is outside of the bounds of the array of text fields'
* First throw call stack:
(0x1c42012 0x1737e7e 0x1c41deb 0xa7f0f0 0xb5d0 0xa72020 0x174b705 0x682920 0x6828b8 0x743671 0x743bcf 0x742d38 0x6b233f 0x6b2552 0x6903aa 0x681cf8 0x1fc2df9 0x1fc2ad0 0x1bb7bf5 0x1bb7962 0x1be8bb6 0x1be7f44 0x1be7e1b 0x1fc17e3 0x1fc1668 0x67f65c 0x29fd 0x2925 0x1)
libc++abi.dylib: terminate called throwing an exception
I will apreciate any suggestions. Thank you in advance.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
UITextField *field = [alertView textFieldAtIndex:0];
setTime = [field.text intValue];
This is error, your second alertView doesn't contain any textField. As in documentation says:
Retrieve a text field at an index - raises NSRangeException when textFieldIndex is out-of-bounds.
The field at index 0 will be the first text field (the single field or the login field), the field at index 1 will be the password field.
This is a solution that should work
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 101 && buttonIndex == 0) {
UITextField *field = [alertView textFieldAtIndex:0];
setTime = [field.text intValue];
NSLog(#"%d", setTime);
...
}
Crash is due to your second alert view don't have a textfield. But you are trying to access the textfield and it's value from the clickedButtonAtIndex:regardless which alerview is clicked.
Implement like: clickedButtonAtIndex
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 101)
{
UITextField *field = [alertView textFieldAtIndex:0];
setTime = [field.text intValue];
NSLog(#"%d", setTime);
if( buttonIndex == 0)
{
NSLog(#"Ok");
[self setTimer];
[self countDownTimerPrepare];
[self countDownTimerIntro];
[self prepareForIntroAnimation];
[self performIntroAnimation];
[self categoriesList];
}
else if (buttonIndex == 1)
{
NSLog(#"Cancel");
ChooseViewController * controller = [[ChooseViewController alloc] initWithNibName:#"ChooseViewController" bundle:nil];
[self presentViewController:controller animated:YES completion:nil];
}
}
else if (alertView.tag==102)
{
if(buttonIndex == 0)
{
NSLog(#"Restart");
}
else if (buttonIndex == 1)
{
NSLog(#"Exit");
}
}
}
Axel, the same problem as in previous case
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
if (alertView.tag == 101){
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if( [inputText length] >= 1 ){
return YES;
}
else{
return NO;
}
}else{
return NO;
}
}

iOS UIAlertView Other Button Action

I have this code currently for my UIAlertView:
if (counter > highscore) { //if highscore is achieved show an alert
highscore = counter;
NSString *nssHighscore = [NSString stringWithFormat:#"%i", highscore];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Congratulations, You Got A New High Score!!"
message:nssHighscore
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Share"];
[alert show];
}
I want to run this code when the 'Share' button is clicked on the Alert
- (IBAction)PostToFacebook:(id)sender {
NSString *nssHighscore = [NSString stringWithFormat:#"%i", highscore];
mySLComposerSheet = [[SLComposeViewController alloc] init];
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[mySLComposerSheet setInitialText:[NSString stringWithFormat:#"My New Highscore is %d - Try to Beat it!, highscore]];
[self presentViewController:mySLComposerSheet animated:YES completion:nil];
}
So far I've been following guides and questions on stack overflow but can't get it working.
Thanks
You'll want to use the alertView:clickedButtonAtIndex: delegate method, and check that the index matches [alertView firstOtherButtonIndex].
Like this:
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Congratulations, You Got A New High Score!!"
message:nssHighscore
delegate:self // <== changed from nil to self
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Share"];
And in the same class:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == [alertView firstOtherButtonIndex]) {
[self PostToFacebook:self];
}
}

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
{
}

NSAlert Input Box, Validating NSTextField

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