I am using multiple UIAlertViews in my code as follows
-(void) myfunc
{
myAlertView1 = [[UIAlertView alloc] initWithTitle:#"Message" message:[list objectAtIndex:1] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlertView1 show];
[myAlertView1 release], myAlertView1 = nil;
{
do something
}
myAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:[list objectAtIndex:1] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlertView show];
[myAlertView release], myAlertView = nil;
}
When I run the program in simulator
I see myAlertView1 (Message) briefly and it does not waits for Ok button click
then I see myAlertView (Error) which waits for Ok button click and after that I again see myAlertView1 (Message) and it waits till OK button is clicked.
Logically I want to see myAlertView1(Message) and wait till Ok button is clicked and then see myAlertView (Error ) and wait till button is clicked.
Am I missing something here?
UIAlertView is not modal as one might expect. You should wait for your delegate to recieve alertView:didDismissWithButtonIndex: before creating and showing the second UIAlertView
Here is how you can make your dialog modal.
I ran into this while researching a similar question from a MonoTouch/C# user, so I wrote this sample for him. The same sample can be trivially ported to Objective-C.
To do this, what you can do is to run the mainloop manually. I have not managed to stop the mainloop directly, so I instead run the mainloop for 0.5 seconds and wait until the user responds.
The following function shows how you could implement a modal query with the above approach:
int WaitForClick ()
{
int clicked = -1;
var x = new UIAlertView ("Title", "Message", null, "Cancel", "OK", "Perhaps");
x.Show ();
bool done = false;
x.Clicked += (sender, buttonArgs) => {
Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex);
clicked = buttonArgs.ButtonIndex;
};
while (clicked == -1){
NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
Console.WriteLine ("Waiting for another 0.5 seconds");
}
Console.WriteLine ("The user clicked {0}", clicked);
return clicked;
}
Here you can do it as follows:
-(void) myfunc
{
myAlertView1 = [[UIAlertView alloc] initWithTitle:#"Message" message:[listobjectAtIndex:1] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlertView1 show];
[myAlertView1 release], myAlertView1 = nil;
{
do something
}
}
And when you get alertview, you can click OK button which calls another method to open another alertview.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==0)
{
[self open_secondAlert];
}
}
-(void)open_secondAlert
{
myAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:[list objectAtIndex:1] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlertView show];
[myAlertView release], myAlertView = nil;
}
Please let me know if you still have any questions.
Thanks,
Best Regards,
Gurprit
Related
I am already aware of the fact that there is an option for us to send sms programmatically i.e. using MFMessageComposeViewController, but is it possible to schedule the message to the specified recipient. I am currently using the following code to send sms:
Class smsClass = (NSClassFromString(kMessageComposer));
if(smsClass != nil && [MFMessageComposeViewController canSendText])
{
MFMessageComposeViewController *smsSendController = [[[MFMessageComposeViewController alloc] init] autorelease];
smsSendController.messageComposeDelegate = self;
smsSendController.body = messageBodyView.text;
smsSendController.recipients = [[[NSArray alloc]initWithObjects:numberField.text,nil]autorelease];
if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 6.0)
{
[self presentViewController:smsSendController animated:YES completion:nil];
}
else
{
[self presentModalViewController:smsSendController animated:YES];
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result)
{
case MessageComposeResultCancelled:
{
UIAlertView *smsCancelledAlert = [[UIAlertView alloc] initWithTitle:kApp message:kCancel
delegate:self cancelButtonTitle:kOk otherButtonTitles: nil];
[smsCancelledAlert show];
[smsCancelledAlert release];
}
break;
case MessageComposeResultFailed:
{
UIAlertView *smsFailedAlert = [[UIAlertView alloc] initWithTitle:kApp message:kError
delegate:self cancelButtonTitle:kOk otherButtonTitles: nil];
[smsFailedAlert show];
[smsFailedAlert release];
}
break;
case MessageComposeResultSent:
{
UIAlertView *smsSentAlert = [[UIAlertView alloc]initWithTitle:kApp message:kSent delegate:self cancelButtonTitle:kOk otherButtonTitles:nil, nil];
[smsSentAlert show];
[smsSentAlert release];
}
break;
default:
break;
}
if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 6.0)
{
[self dismissViewControllerAnimated:YES completion:nil];
}
else
{
[self dismissModalViewControllerAnimated:YES];
}
}
I also would like to know whether this code works perfect in all versions above 4.3 till date 6.0. As of now I don't have the device available to test this. So would need some answers from some one who experienced this code as working/failed.
In addition to this, I would want to schedule the message i.e. user specified date&time and the process should be running in background without any user interaction.
How to achieve this?
With MFMessageComposerViewController it is not possible to send without user interaction.
you may consider creating a custom webservice to sms gateway to do achieve this
using the debugger I've ensured [alertView show]; is being called, but the dialog is not viewable, what else do I need to do to get it to show?
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if( [[userInfo objectForKey:#"aps"] objectForKey:#"alert"] != NULL)
{
NSString *msg = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
if(msg != nil) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Usage Alert"
message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alertView show];
}
}
}
In your view controller .h file, you need to declare the <UIAlertViewDelegate> Like this, before the opening curly braces, encapsulated with greater than and less than symbols:
#import <UIKit/UIKit.h>
#interface YourViewControllersName : UIViewController <UIAlertViewDelegate> {
// your variable declarations are here...
}
// your method declarations are here...
Sorry everyone, this turned out to be an issue with my compiler/xCode not actually recognizing the code I had put in or something along those lines, the environment was broken.
I want to check if the text inserted in a textfield is also in my NSMutableArray.
So let's say my NSMutableArray has these objects: "Hey, Hello, No, Yes".
Then when a user enters the text: "Hello" i want there to appear a UIAlertView. I now have the following:
for (int slt = 0; slt < [zouten count]; slt++) {
if (zout.text = [zouten objectAtIndex:slt]) {
alert = [[UIAlertView alloc]initWithTitle:#"Goedzo!" message:[NSString stringWithFormat:#"Je hebt een zout gevonden"] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
}
[alert show];
But somehow the message appears with every word. what am i doing wrong?
When you compare like this:
if (zout.text = [zouten objectAtIndex:slt])
you are actually assigning instead of comparing so it will be TRUE always.Therefore instead of using =, you should compare like this:
if ([zout.text isEqualToString:[zouten objectAtIndex:slt]])
Your code should be:
for (int slt = 0; slt < [zouten count]; slt++) {
if ([zout.text isEqualToString:[zouten objectAtIndex:slt]]) {
alert = [[UIAlertView alloc]initWithTitle:#"Goedzo!" message:[NSString stringWithFormat:#"Je hebt een zout gevonden"] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
break;
}
}
You can use isEqualToString method to compare strings.
if([zout.text isEqualToString:[zouten objectAtIndex:slt]])
Alternatively you could make your code more concise by converting to a set and checking for the entry, e.g.
NSSet *set = [NSSet setWithArray: zouten];
if([set containsObject:zout.text]) {
...
}
I'm currently working in Xcode on an iOS app...
I've set up a UIAlertView (with a question as the message ) to pop up with a text field to retrieve a response.
The desired functionality is that upon entering an incorrect value into the text field, the UIAlert would loop... Until the correct response is entered. At this point, the UIAlert would be dismissed.
Heres what I have so far...
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
NSString* correctAnswer = #"2";
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Alarm"
message:#"1 + 1 ="
delegate:self
cancelButtonTitle: nil
otherButtonTitles:#"Continue", nil ];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField* answerField = [alert textFieldAtIndex:0];
answerField.keyboardType = UIKeyboardTypeNumberPad;
answerField.placeholder = #"answer";
[alert show];
// I feel like this would work, but I know it doesn't...
NSString *answerFieldString = answerField.text;
if ([answerFieldString isEqualToString: correctAnswer ])
{
[alert dismissWithClickedButtonIndex:-1 animated:YES];
}
}
I've done extensive google searching and can't come up with a solution... Any responses would be much appreciated!
try this...
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
NSString *answerFieldString = answerField.text;
if ([answerFieldString isEqualToString: correctAnswer ])
{
[alertView dismissWithClickedButtonIndex:-1 animated:YES];
}
}
I'm sick of writing basic UIAlertView's, ie:
UIAlertView *alert = [[UIAlertView alloc] initWith...]] //etc
Instead of doing this, is it possible to put all this in a "helper" function, where I can return the buttonIndex, or whatever an alert usually returns?
For a simple helper function I guess you could feed parameters for the title, message, I'm not sure whether you can pass delegates in a parameter though, or bundle info.
In pseudo-code, it could be like this:
someValueOrObject = Print_Alert(Title="", Message="", Delegate="", Bundle="") // etc
Any help on this would be great.
Thanks
In 4.0+ you can simplify the alert code using blocks, a bit like this:
CCAlertView *alert = [[CCAlertView alloc]
initWithTitle:#"Test Alert"
message:#"See if the thing works."];
[alert addButtonWithTitle:#"Foo" block:^{ NSLog(#"Foo"); }];
[alert addButtonWithTitle:#"Bar" block:^{ NSLog(#"Bar"); }];
[alert addButtonWithTitle:#"Cancel" block:NULL];
[alert show];
See Lambda Alert on GitHub.
This is what I wrote, when I got sick of doing the same:
-(void)alert:(NSString *)title withBody:(NSString *)message firstButtonNamed:(NSString *)firstButtonName {
[self alert: title withBody: message firstButtonNamed: firstButtonName withExtraButtons: nil informing: nil];
}
-(void)alert:(NSString *)title withBody:(NSString *)message firstButtonNamed:(NSString *)firstButtonName informing:(id)delegate {
[self alert: title withBody: message firstButtonNamed: firstButtonName withExtraButtons: nil informing: delegate];
}
-(void)alert:(NSString *)title withBody:(NSString *)message firstButtonNamed:(NSString *)firstButtonName withExtraButtons:(NSArray *)otherButtonTitles informing:(id)delegate {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate: delegate
cancelButtonTitle: firstButtonName
otherButtonTitles: nil];
if (otherButtonTitles != nil) {
for (int i = 0; i < [otherButtonTitles count]; i++) {
[alert addButtonWithTitle: (NSString *)[otherButtonTitles objectAtIndex: i]];
}
}
[alert show];
[alert release];
}
You can't write a function that will display an alert and then return a value like a buttonIndex though, because that value-returning only occurs when the user presses a button and your delegate does something.
In other words, the process of asking a question with the UIAlertView is an asynchronous one.