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.
Related
I just want to know how to prevent my alert view from appearing everytime I open my application that's already connected to the internet. I'm using ARC if that helps.
This is the code I have in my didFinishLaunchingWithOptions method inside my AppDelegate:
__weak id myself = self; // to silence warning for retain cycle
_httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://apple.com"]];
[_httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status) {
case AFNetworkReachabilityStatusNotReachable:
{
// Not reachable
NSLog(#"Not connected to the internet");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Not connected to the internet" delegate:myself cancelButtonTitle:nil otherButtonTitles:#"Dismiss", nil];
[alert show];
break;
}
case AFNetworkReachabilityStatusReachableViaWiFi:
{
NSLog(#"Connected to the internet via WiFi");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Connected to the internet via WiFi" delegate:myself cancelButtonTitle:nil otherButtonTitles:#"Dismiss", nil];
[alert show];
break;
}
case AFNetworkReachabilityStatusReachableViaWWAN:
{
NSLog(#"Connected to the internet via WWAN");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Connected to the internet" delegate:myself cancelButtonTitle:nil otherButtonTitles:#"Dismiss", nil];
[alert show];
break;
}
default:
break;
}
}];
Echoing #D80Buckeye: just don't pop an alert for reachability. It's completely unnecessary, and doesn't add anything to the user experience (it's not like the user can do anything to fix a lack of reachability like that). If anything, you could show a non-modal indication of network reachability.
How about creating a global flag
static BOOL g_FirstTime = YES;
and check it before displaying alert view
if (g_FirstTime) {
g_FirstTime = NO;
break;
}
NSLog(#"Connected to the internet via WiFi");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Connected to the internet via WiFi" delegate:myself cancelButtonTitle:nil otherButtonTitles:#"Dismiss", nil];
[alert show];
break;
Without knowing the scope of your project it's hard to make a solid suggestion. My whole-hearted suggestion is that you do NOT want to do a pop-up every time the end user bounces back on the network. If you have code implemented that is reliably detecting a refreshed network connection, if I were you, I would put some sort of subtle (but obvious) on-screen indicator like a small icon/image or maybe even a UILabel that says "connected" or "disconnected" or whatever verbiage works for you. As others have suggested I would completely steer clear of instantiating a pop-up of any sort for that alert.
Regarding the code itself - get very familiar with View Controller Programming and iOS App Programming Guide. Between those two documents you can properly map out how to detect and react to when your app comes in and out of the background state, when it launches, when it becomes active, when your views appear/load, etc. Combine those methods & calls with some global state-driven variables and you should be well on your way.
Bottom line is you want to get familiar with those app state documents as well as [[NSNotificationCenter defaultCenter] addObserver:<#(id)#> selector:<#(SEL)#> name:<#(NSString *)#> object:<#(id)#>]
Let me know if that doesn't make sense.
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];
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
Hello and good afternoon, I'm having some issues here, and to be honest, I don't understand
I have to create different alertViews for the same screen with different messages, most of these alerts only have 1 button, but there's this one to delete that needs 2 buttons, the thing is that, since the others have only 1 button, when I created the 2 button screenview and I added the (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex method, I have some problems
some code here
- (IBAction)saveInfo{
if (med.text.length ==0) {
UIAlertView *alertViewError = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"ERROR",#"")
message:NSLocalizedString(#"EMPTY1",#"")
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertViewError show];
[alertViewError release];
}
else if(medicamento.text.length >= 41){
[self lenghtError:40:NSLocalizedString(#"TF_MED",#"")];
}
else if (med.text.length ==0 || descripcion.text.length == 0) {
UIAlertView *alertViewError = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"ERROR",#"")
message:NSLocalizedString(#"EMPTY2",#"")
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertViewError show];
[alertViewError release];
}
else if (descripcion.text.length >= 41){
[self lenghtError:40:NSLocalizedString(#"TF_DESCRIPCION",#"")];
}
else{
[self insertDictionary];
UIAlertView *alertViewAcept = [[UIAlertView alloc] initWithTitle:#""
message: NSLocalizedString(#"ACCEPT_MSG",#"")
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertViewAcept show];
[alertViewAcept release];
[self.navigationController popViewControllerAnimated:YES];
}
}
- (IBAction)cancelData{
UIAlertView *alertViewCancel =
[[UIAlertView alloc] initWithTitle: NSLocalizedString(#"BT_DELETE_MED",#"")
message: NSLocalizedString(#"MSG_DELETE_MED",#"")
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: #"Cancel", nil];
[alertViewCancel setTag:999];
[alertViewCancel show];
[alertViewCancel release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 999) {
if(buttonIndex==0){
[self.Bayer_DB_obj deleteRowWithKeyValue:[NSString stringWithFormat:#"%d",IdMed] onKeyName:#"id_ctl_med" onTable:#"ctl_med"];
// code to delete here
[self.navigationController popViewControllerAnimated:YES];
}
}
}
So, in the first part, I created some alerts to indicate the user that he/she is making a mistake, in the second part, I need a confirmation before deletion, but here, I need 2 buttons, then, in the 3rd part, I have the method that is been called, I added a tag to my alert to avoid doing this comparison in all the alerts, the problem is that, when you show alertViewAcept, it takes you to the previous view controller, and after you click the ok button (that actually is the cancelbuttontitle) the app crashes without any "error message"
so I'm not sure what I'm doing wrong, please help
My guess the problem is that you set the delegate for the alertViewAcept, and right after you showed the alert, you pop the viewController and so your delegate will get released, which will then give you an error once a button on the alert view is clicked.
You should do this:
UIAlertView *alertViewAcept = [[UIAlertView alloc] initWithTitle:#""
message: NSLocalizedString(#"ACCEPT_MSG",#"")
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
Even better, all your alerts which only have the OK button, do not need a delegate. And in that case you do not even need the tag.
i have a project with many vie controller, in one of these i create and show a view alert. it's possible show alert in every view exclude one?
I need this because if you are in the alarm view controller you don't need to see the alert when alarm ring
i try this but not works!
// ALERT NOTIFICATION
if (!self.timerViewController) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Piccole Ricette" message:#"READY" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
[alertView release];
}
In iOS you can test whether a ViewController 's view is visible by testing the view's window property. If the view is not visible the window property will be nil. So perhaps you can do something like this:
if (!self.timerViewController.view.window) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Piccole Ricette" message:#"READY" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
[alertView release];
}