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