Close UIAlertView and Replace with Another - iphone

I'm running an application that requires LocationServices be enabled. I'm checking if they are by making a call to the service and catching the error. In the error case, I want to pop up an alertview notifying the user to activate location services. I have another AlertView open already when this test happens. I want to close that one and give the user the dialog box I mentioned previously.
Currently, I have
case kCLErrorDenied: // CL access has been denied (eg, user declined location use)
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"NOTICE"
message:#"Sorry, this application needs your location. Please select 'Allow' when asked to use your current location. You don't need to be on or near the trail."
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"EXIT"];
[alert show];
[alert release];
//exit(0);
break;
This causes the app to just exit. I had an NSLog output in there so I know it gets to this case.

here you are specifying delegate:self, then it searches for alert handlers declared at UIAlertViewDelegate and when it doesn't find it crashes.
So you should define
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
in your class.
Also you can implement other methods of UIAlertViewDelegate which will help you in your required task.

You need to keep track of the previous alert with an instance variable, and call the method to dismiss that previous dialog before showing the new one. You also need a delegate handler for the alert.

Related

How to exit the app after an error in user friendly manner?

I need to protect my code against possible errors. If they arise then there's no point to run the app further, so I need to bring to the user some message and then exit the app. So, I'm checking the conditions and then bringing alert:
if (someError){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"No database file exist. App will close now." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
And in the delegate method I'm closing the app using NSAssert:
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSAssert(0, #"closing");
}
}
Also, I have included delegate protocol in header. However, the app just brings alert but after pressing OK it just freezes, and I'm getting some message "CoreAnimation: ignoring exception: closing". What am I missing or what other options exits?
You should not do that, it is against Apple HIG (Human Interface Guidelines):
iPhone applications should never quit programmatically because doing so looks like a crash to the user.
It is always better to provide some kind of feedback to the user about the error that occured and provide a way to restart the process without restarting the app. However, if you really, really want, you can use
exit(0);

Iphone: stop execution of code when alert is shown in a viewWillAppear implementation

I have a working application
before the first view is loaded, i put an alert in the viewWillAppear method:
- (void)viewWillAppear
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"MyAppp" message:#"Application will connect to Internet. Continue?"
delegate:self cancelButtonTitle:nil otherButtonTitles:#"No, quit", #"Yes", nil];
[alert show];
[alert release];
}
I can get the clicks on the two button (Yes/No) correctly...
But...I would like code execution to stop and wait for an answer, but instead the code goes on, connects to the internet and retrieves data...
How do I prevent a view to load, based on a user input?
The viewWillAppear is a notification which allows you to complete some stuff before the view is shown, you can't avoid the appearing of the view here. You have to review your implementation.
Just break your one viewWillAppear method into two methods. Don't try to do it all in one chunk of sequential code.
The first method will launch the alert and then just exit/quit/return.
The second method can be called by the alert button response handler, and then finish loading the view only after it's been called by the alert handler, after the user has responded.
You may or may not have to save extra state information (in extra properties or instance variables instead of method locals) between the first and second methods.
the below can be used, i know its little old question but might be useful for others
..
[alert show];
while ((!alert.hidden) && (alert.superview != nil))
{
[[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];
}
I solved it by showing the answer in the "ViewDidLoad", got a delegate to get which button was pressed and then processing the data ONLY if the user pressed "Yes"

Objective C - Making UIAlertView wait for user input?

I have a UIAlertView set up with a textfield like so:
//***first set of code***
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"User Input Required" message:#"Please enter data into the field" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alert addTextFieldWithValue:nil label:#"[Enter Text]"];
[[alert textField] becomeFirstResponder];
[alert show];
[alert release];
//***second set of code***`
How can I make it so that the user is required to click a button (I have that method already set up to send the input to a string) BEFORE any of the 'second set of code' is fired off?
I need that second set of code to be contained in the same section as the alert (so I can't just run it within the 'dismissWithClickedButtonIndex' method) and that second set of code is using the string obtained from the user input, so that is why I don't want that code to run prior to the user clicking a button.
Don't you just love it when people say "don't do it that way"... and then never give you any good/correct way you SHOULD be doing it.
Thanks.
You can't do that. show message in UIAlertView won't stop for user input. Associated delegates will need to handle the code you are planning to put in //***second set of code*** section.
Having said that, let me give you some advice. addTextFieldWithValue message is an undocumented API feature. Do not use it. It used to be a long time ago that approval process from Apple for you APP would let you pass even if your application used that addTextFieldWithValue message. But nowadays that does not happen anymore. Your application will be automatically rejected if it is using that undocumented feature. Here is a blog entry on the topic.
Hope it helps.

What class handles the popup/notification windows on iphone?

I'm looking for the class name of the popup/message windows on the iPhone (it's a blueish window that comes up when you have a missed call, or a message comes in for example.)
The class is called UIAlertView. From the documentation:
Use the UIAlertView class to display an alert message to the user. An alert view functions similar to but differs in appearance from an action sheet (an instance of UIActionSheet).
Use the properties and methods defined in this class to set the title, message, and delegate of an alert view and configure the buttons. You must set a delegate if you add custom buttons. The delegate should conform to the UIAlertViewDelegate protocol. Use the show method to display an alert view once it is configured.
The examples you gave (missed call or incoming text message) are system level alerts that pop up over any application. That functionality is not available through the SDK. lajos's answer does provide the correct way to display an alert, but it is worth remembering you can only do this within your application. You cannot pop up an alert over another app because the SDK currently prohibits an app from running in the background.
Further to this response, UIAlertView is indeed the way to do this and the code you want is:
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Message" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
[alert show];
Here the alert box will popup with the message "Message" and have a single button titled "OK" which will close the popup when clicked. Check the documentation for other things you can do (more buttons etc).

Bug in AlertView on iPhone?

I write a piece of code to "do something->show alert1->do something->show alert2".
//do something
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Alert 1"
message:nil
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
//do something
UIAlertView *alert2 = [[UIAlertView alloc]
initWithTitle:#"Alert 2"
message:nil
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert2 show];
[alert2 release];
And suddenly a strange thing happened to multiple AlertViews: It shows "Alert 1"->"Alert 2"(Press 'OK')->"Alert 1". Why "Alert 1" shows again? I haven't written any delegate method yet. Maybe a bug?(Thanks to cobbal, alert1 is still there when alert2 appears.)
I find -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex works well. Is the delegate method a common way to show multiple alertViews?
I would guess that alert 1 is shown and then covered by alert 2 since show isn't modal. When alert 2 is closed, alert 1 is still open.
To your second question, alertView:didDismissWithButtonIndex: may work better, but I haven't actually tested that.
The delegate is so that you can be notified when the alert is dismissed, and which button was used to dismiss it. It doesn't impact whether the alert is dismissed at all.
The alert will remain visible until it is dismissed either by you tapping a button (if any - they are not required) or you call either [UIAlertView dismissWithClickedButtonIndex:animated] or the (undocumented) dismiss method of the alert instance.
It looks like (as Cobbal suggested), alert 2 is popping up over alert 1, you dismiss alert 2, and alert 1 remains there (until it itself is dismissed).
Is there a particular reason you want to show a new alert while another is still showing? Perhaps some more context would help us to get to the root of the issue, which I suspect may be a design issue.
[edit] coming back to this and reading again, I wonder if what you are asking about with the delegate method is whether you should be showing alert 2 from there? In which case that's probably what you want - whether directly or indirectly. By indirectly I mean that you may have some state set elsewhere that determines whether alert 2 should be shown (or the circumstances that lead to it). That state (a flag, perhaps) could be set when you show the first alert, and cleared when the alert is dismissed (from the delegate method).
The reason this happens is because UIAlertView doesn't block while it's showing. Any code written after showing an alertview will run straight after the alert is shown.
What you should have is two different methods. One that does something and then shows an alert, and then another that does something and shows another alert.
Kick off the first method to do something and show an alert, and then hook into the alert's delegate method, and when you get the callback from the alertview, run the other method.
This way, the second part of the process won't happen until the user has pressed OK on the alert in first part of the process.