Why isn't UIAlertView Showing? - iphone

For some reason screen gets dark and freezes, alert is not shown... can someone please help?
Thanks in advance!
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello!"
message:#"Hello!" delegate:self
cancelButtonTitle:#"Done"
otherButtonTitles:nil];
[alert show];
[alert release];
}

You are probably calling show from a background thread, call it on the main thread like this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello!"
message:#"Hello!" delegate:self
cancelButtonTitle:#"Done"
otherButtonTitles:nil];
[alert performSelectorOnMainThread:#selector(show)
withObject:nil
waitUntilDone:NO];
[alert release];

Delegate is correct, but maybe because your do a release at the end it may cause a problem.
Try with a nil delegate :-)
For example :
UIAlertView *alertView;
alertView = [ [ UIAlertView alloc ] init ];
[ alertView setMessage:#"Hello World" ];
[ alertView show ];
[ alertView release ];
If it works, then it was the delegate and you need to declare the variable as a class var. Or it maybe be elsewhere.

Is this alert maybe sitting in a big loop and you are not running on multiple threads? The screen darkening and nothing happening is something I equate with running a long process on the main thread (so the UI doesn't refresh and show the alert).

You get a dark screen without a popup, or slower popup if you show the UIAlertView from a background thread. Just out it back in the main thread and it will be fine. I just had this problem last week.

Related

Why is app crashing when showing UIAlertView?

I've implemented the Reachability function in a method that handles all the server requests. I can see through NSLogs that the function works perfectly. However there is never a "pause" within the method which means I can't use the UIAlertView without crashing the program.
I might be going at this the completely wrong way, but I can't find anything else...
Does anybody have an idea of how to get a notification to show somehow?
Thanks in advance
CODE:
-(id) getJson:(NSString *)stringurl{
Reachability * reach = [Reachability reachabilityWithHostname:#"www.google.com"];
NSLog(#"reached %d", reach.isReachable);
if (reach.isReachable == NO) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Passwords don't match."
message:#"The passwords did not match. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}else{
id x =[self getJsonFromHttp:stringurl];
return x;
}
return nil;
}
After moving the discussion to a chat, we discovered that your UIAlertView was being called from a background thread. Never do anything related to updating the UI (User-Interface) in a background thread. The UIAlertView updates the UI by adding a little pop-up dialog, so it should be done on the main thread. Fix by making these changes:
// (1) Create a new method in your .m/.h and move your UIAlertView code to it
-(void)showMyAlert{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Passwords don't match."
message:#"The passwords did not match. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
// (2) In -(id)getJson replace your original UI-related code with a call to your new method
[self performSelectorOnMainThread:#selector(showMyAlert)
withObject:nil
waitUntilDone:YES];

dismissing a UIAlertView programmatically

I need help on dismissing a UIAlertView programmatically. Currently I have this
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"title" message:#"message" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
then later on I call this
[alert1 dismissWithClickedButtonIndex:0 animated:NO];
but nothing happens.
You need to set two things.
1. include your .h file : <UIAlertViewDelegate>
2. please follow below implementation...
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"title" message:#"message" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[alert1 show];
[self performSelector:#selector(dismiss:) withObject:alert1 afterDelay:1.0];
the dismiss method will be...
-(void)dismiss:(UIAlertView*)alert
{
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
I hope this will help you.
I encountered this problem too.
In my case, for some reason calling:
[alert dismissWithClickedButtonIndex:0 animated:NO];
didn't work always (yes, even calling it on UI thread and yes, alert != nil), instead simply setting the animated flag to YES it worked:
[alert dismissWithClickedButtonIndex:0 animated:YES];
Maybe it's an Apple bug...
you should display it first:
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"title" message:#"message" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert1 show];
then in delegate method
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{
if(buttonIndex==0){
// do something
}
}
The methods you called is correct.
I guess the alert1 is nil when your call the method dismissWithClickedButtonIndex:animated:
Try to check your variable alert1.
You can use the delegate method -alertView:didDismissWithButtonIndex: instead—it gets called once the alert view’s been removed from the screen, OR better approach is , use a background thread, e.g. with -performSelectorInBackground:withObject:, to handle whatever processing you need to do.

Executing a snippet of code in the AlertView OK button declaration

in my Alert View, there is two button, OK and Cancel. When the user click the OK button, the delegate method dismissWithClickedButtonIndex:animated get called, and if the index is 0, then i get called to a method to execute some code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Are you sure you want to exit"
delegate:self cancelButtonTitle: #"OK"
otherButtonTitles: #"Cancel",nil];
[alert show];
[alert release];//release the reference
Delegate method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
if (buttonIndex==0) {
[self aMethod];
}
}
-(void)aMethod{
//Some useful code
}
Now, what i want to instead of all this, is to execute the code of the aMethod method in the AlertView directly, without referring to A delegate method and a method which get called, something like that:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Are you sure you want to exit"
delegate:self cancelButtonTitle: #"OK" //Put here some useful code
otherButtonTitles: #"Cancel",nil];
Is it possible?
Unfortunately this is not possible at this time (iOS 5.1). The AlertView class does not support blocks.
I made a pair of UIAlertView and UIActionSheet subclasses that do exactly that. Grab them here:
https://github.com/rydermackay/RMActionSheet
Use them like this:
RMAlertView *alertView = [RMAlertView alertViewWithTitle:#"Alert!" message:nil];
[alertView addButtonWithTitle:#"OK"
action:^{
NSLog(#"OK");
}];
[alertView addCancelButtonWithTitle:#"Cancel"
action:nil];
[alertView show];
EDIT:
From your comments it sounds like you're not familiar with blocks. Read this now. Seriously.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html
This is a good one too:
http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html

Show UIAlertView in background thread

I load data from a webservice in a background thread. Is it safe to show an UIAlertView in the background thread when anything goes wrong or should I show the alert view in the mainthread ?
thanks for the advice
Frank
Never do anything with the GUI except from the main thread. It can cause very weird issues and or crashes you don't want to deal with. Usually the backtraces are also very unhelpful so try to avoid such issues by default.
Therefore use this:
[self performSelectorOnMainThread:#selector(showAlert:) withObject:alertString waitUntilDone:NO];
If you are using grand Central dispatch you could do something like:
dispatch_async(dispatch_get_main_queue(), ^{ /* show alert view */ });
Update:
Swift (3.0+):
DispatchQueue.main.async { // code }
It is sometimes helpful to do this with Notifications you receive as well, I have had instances where they were fired from a different thread.
Update 2:
It looks like apple has added some new tools coming in iOS11/Xcode9 to help debug issues where stuff is called on the incorrect thread.
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
});
this code works for me
You could try showing the alert on the main thread by:
UIAlertView *alert = [
[[UIAlertView alloc] initWithTitle:#"the title"
message:#"the message"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil] autorelease];
[alert performSelector:#selector(show)
onThread:[NSThread mainThread]
withObject:nil
waitUntilDone:NO];
[alert release];

IPHONE: UIAlertView called twice in a custom function/IBAction

i have an IBAction which does some processing and within will have a few UIAlertViews (to show alerts). However it seems that the FIRST alert in the paragraph is being called TWICE (once immediately after i clicked and another time after all the other alerts has occured). Additionally, the first time the alert appears, the alert automatically closes even though i have an OK button and the user has not clicked on it. The 2nd time the alert appears, it will require the user to click on OK.
I tried moving the paragraph out from IBAction into its own function but still the problem occurs.
all the alerts in my IBAction/function are the same:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"blah" message:#"blah" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alert show];
[alert release];
but the other alerts function normally.
the code looks like this ("blah" is the one being called twice):
-(void)function {
if (......) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"blah" message:#"blah" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alert show];
[alert release];
for (int i=0; i<2; i++) {
if (.....) {
//do stuff
} else {
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"blah2" message:#"blah2" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alert2 show];
[alert2 release];
}
}
} else {
UIAlertView *alert3 = [[UIAlertView alloc] initWithTitle:#"blah3" message:#"blah3" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alert3 show];
[alert3 release];
}
}
please help!
First of all, we need more code to diagnose your problem. What you provide is not sufficient.
Second, I once encountered a similar problem: when a compose an email action is triggered by the user who didn't set up her email account on that device, I asked my app to show an UIAlertView. However, when I tested my code on a real device with such a scenario, two consecutive UIAlertViews showed, one after another, both of which are about the email account not set up issue.
I finally figured out that the iOS system will automatically show an UIAlertView when the email account is not set up while a user tries to compose an email, which is why two UIAlertViews showed up when I only expected one.
Hope that helps.