Using buttonIndex with multiple alert views - ios

I have about 4 alert views with different criteria when they appear. In all 4 views, the right button should always do the same thing.
I use the code below to try and say IF the buttonIndex == 1, do something.
Currently, It only works in one of my alert views. The others just end up closing the alert view and never running the code for IF buttonIndex == 1.
Any ideas would be appreciated.
if (a==1) {
NSString *message = [[NSString alloc] initWithFormat:
#"Only $%#!",dollas.text];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
#"Really?!"
message:message
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:#"Facebook",nil];
[alert show];
[alert release];
[message release];
}
else if (a==2) {
NSString *message = [[NSString alloc] initWithFormat:
#"Somone just paid you $%#", dollas.text];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
#"Swish!"
message:message
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles:#"Facebook",nil];
[alert show];
[alert release];
[message release];
}
And the delegate:
- (void)alertView:(UIAlertView *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1)
{
do.stuff;
}

You should be setting the delegate to self so that method gets called.
IE -
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
#"Really?!"
message:message
delegate:self //SELF
cancelButtonTitle:#"Close"
otherButtonTitles:#"Facebook",nil];

Set the tags on each alertview and inside -didDismissWithButtonIndex check first for the alerts tag
eg:
if (a==1) {
NSString *message = [[NSString alloc] initWithFormat:
#"Only $%#!",dollas.text];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
#"Really?!"
message:message
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:#"Facebook",nil];
alert.tag = 1;
[alert show];
[alert release];
[message release];
}
else if (a==2) {
NSString *message = [[NSString alloc] initWithFormat:
#"Somone just paid you $%#", dollas.text];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
#"Swish!"
message:message
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles:#"Facebook",nil];
alert.tag = 2;
[alert show];
[alert release];
[message release];
}
then in -didDismissWithButtonIndex
- (void)alertView:(UIAlertView *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1 && actionSheet.tag == 1)
{
do.stuff;
}
else if (buttonIndex == 1 && actionSheet.tag == 2)
{
do.otherStuff;
}

For the case (a == 2) you set the UIAlertView delegate to nil, so - (void)alertView:(UIAlertView *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex shouldn't even be getting called for this case. Change it to set the delegate to self.

Related

iOS ARC UIAlertView leaking memory

I have simple method showing AlertView with textfield. Instruments showing memory leak in this. Please explain.
- (void)method {
NSString *value = [[NSUserDefaults standardUserDefaults] valueForKey:#"key"];
if (value == nil) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Title" message:#"message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
alertView.tag = 101;
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *txtGroup = [alertView textFieldAtIndex:0];
[txtGroup becomeFirstResponder];
[alertView show];
alertView = nil;
}
}
Please find the screenshot of Instruments:
You need to create alertView as :
static UIAlertView *alertView = nil;
if (!alertView){
alertView = [[UIAlertView alloc] initWithTitle:#"Title" message:#"message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
}

UIAlertView clickedButtonAtIndex not called when text field is in

When I have the following code the clickedButtonAtIndex delegate method is called:
UIAlertView * alertTextField = [[UIAlertView alloc] initWithTitle:#"Post To Facebook" message:#"What would you like the post to say?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Continue", nil];
alertTextField.tag = 2;
[alertTextField show];
But when i add in the UIAlertViewStylePlainTextInput in the delegate method is not called.
UIAlertView * alertTextField = [[UIAlertView alloc] initWithTitle:#"Post To Facebook" message:#"What would you like the post to say?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Continue", nil];
[alertTextField setAlertViewStyle:UIAlertViewStylePlainTextInput];
alertTextField.tag = 2;
[alertTextField show];
Why is this?
ensure that you added <UIAlertViewDelegate> in your view controller and your forget to add alertTextField.delegate = self; Then implement the delegate to receive the event.
UIAlertView * alertTextField = [[UIAlertView alloc] initWithTitle:#"Post To Facebook" message:#"What would you like the post to say?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Continue", nil];
[alertTextField setAlertViewStyle:UIAlertViewStylePlainTextInput];
alertTextField.delegate = self; // you forget to add this line
alertTextField.tag = 2;
[alertTextField show];
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
NSString *test = [[alertView textFieldAtIndex:0] text];
}
}
UIAlertView no longer available/support in iOS 8 and above so in this place use UIAlertViewController, example for how to use UIAlertViewController see this tutorial

UIAlertView IndexButton

I have this code right here for annotations in my map...
//alert view
if ([ann.title isEqual: #"Al-saidiya"]) {
NSString *msg=#"Phone No : 079011111";
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:#"Call Us", nil];
[alert1 show];
}
else if ([ann.title isEqual: #"Al-Kadmiya"]) {
NSString *msg=#"Phone No : 07902222222";
UIAlertView *alert2 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles:#"Call Us", nil];
[alert2 show];
}
else if ([ann.title isEqual: #"Palestine St"]) {
NSString *msg=#"Phone No : 0790333333";
UIAlertView *alert3 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles: #"Call Us",nil];
[alert3 show];
}
else if ([ann.title isEqual: #"Karada Maryam"]){
NSString *msg=#"Phone No : 07905867";
UIAlertView *alert4 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles:#"Call Us", nil];
[alert4 show];
}
else if ([ann.title isEqual: #"Mansour Office"]) {
NSString *msg=#"Phone No : 07954212";
UIAlertView *alert5 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles: #"Call Us",nil];
[alert5 show];
}
else if ([ann.title isEqual: #"Hunting Club"]) {
NSString *msg=#"Phone No : 079337745";
UIAlertView *alert6 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles: #"Call Us",nil];
[alert6 show];
}
else if ([ann.title isEqual: #"Al-jadriya"]) {
NSString *msg=#"Phone No : 07976231";
UIAlertView *alert7 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles: #"Call Us",nil];
[alert7 show];
}
else if ([ann.title isEqual: #"Al-jamea'a"]) {
NSString *msg=#"Phone No : 07865323";
UIAlertView *alert8 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"ok" otherButtonTitles: #"Call Us",nil];
[alert8 show];
}
}
And when i apply this method ::
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex==1){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"telprompt://576576576"]]];
NSLog(#"It works!");
}
}
it has been applied on every alert objects above there and took the same number.i want every alert object to get its own phone number when i want to call.
Just add a tag to your alert views
if ([ann.title isEqual: #"Al-saidiya"]) {
NSString *msg=#"Phone No : 079011111";
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"Contact" message:msg delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:#"Call Us", nil];
alert1.tag = 0; // <--
[alert1 show];
}
and check the tag in alertView:clickedButtonAtIndex::
if (alertView.tag == 0) {
// call Al-saidiya
}
...
Well even if the solution proposed by tilo works, I think is not the right approach when you have multiple instances of objects like UIAlertview.
I would like to suggest you to use blocks instead.
These categories (the project use the same pattern for UIActionSheet) allow you to bind an action block to a specific button in your alertView.
Using this approach you can get rid of all the if/switch statements using the delegate pattern.
As the title and the phone number is a 1:1 relationship I'd use a dictionary:
NSDictionary *titlesAndMessages = #{#"Al-saidiya" : #"Phone No : 079011111",
#"Al-Kadmiya" : #"Phone No : 07902222222",
#"Palestine St" : #"Phone No : 0790333333"};
...
NSString *messageString = nil;
for (NSString *keyTitle in [titlesAndMessages allKeys]) {
if ([ann.title isEqualToString:keyTitle]) {
messageString = [titlesAndMessages objectForKey:keyTitle];
break;
}
}
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Contact" message:messageString delegate:self cancelButtonTitle:#"ok" otherButtonTitles:#"Call Us", nil];
[alert show];
}
This scales a lot better as you won't have to write any additional code to expand, just add entries to the dictionary (automagically or otherwise).
Using UIAlertViewDelegate is really clumsy. I recommend everyone use PSAlertView for any non-trivial use of alerts.
Using this, the code becomes simple and self contained.
- (void)promptToContact:(NSString *)message
withNumber:(NSString *)phoneNumber
{
PSAlertView *alert = [[PSAlertView alloc] initWithTitle:#"Contact"];
[alert setCancelButtonWithTitle:#"Dismiss" block:^{}];
[alert addButtonWithTitle:#"Call" block:^{
NSString *urlString = [NSString stringWithFormat:#"telprompt://%#", phoneNumber];
NSURL *url = [NSURL urlWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
}];
[alert show];
}
First set the tag in your alertview in above code then in your below method. Try like this:-
-(void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
{
int indexValue=alertView.tag;
switch (indexValue)
{
case 0:
NSLog (#"zero");
//your code
break;
case 1:
NSLog (#"one");
//your code
break;
case 2:
NSLog (#"two");
//your code
break;
case 3:
NSLog (#"three");
// your code
break;
case 4:
NSLog (#"four");
//your code
break;
case 5:
NSLog (#"five");
// your code
break;
...... Up to
case 8:
// your code
break;
default:
NSLog (#"done");
break;
}

action on textFieldDidEndEditing

I want an alert when the following text fields receive the conditions in second section of code
self.circuit.rcdAtIan = [ICUtils nonNilString:self.rcdAtIan.text];
self.circuit.rcdAt5an = [ICUtils nonNilString:self.rcdAt5an.text];
The above code works fine so now I need to fire it. Using the below method was my first thought but that fires the alert on every keyboard resignation. I only want the alert to display once.
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_rcdAtIan.text intValue]> 200) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alert show];
}
if ([_rcdAt5an.text intValue]> 40) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
[alert show];
}
}
Im thinking maybe I need a bool with NSUserDefaults perhaps? but not sure how to implement that to check if the alert has been shown. Normally if I wanted an alert shown once I would do
if (![#"1" isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:#"alert"]]){
[[NSUserDefaults standardUserDefaults] setValue:#"1" forKey:#"alert"];
[[NSUserDefaults standardUserDefaults] synchronize];
[alert show];
}
However in this instance, when the page is reloaded I want the alerts to be shown again and in any case im not sure if thats an efficient way to solve this
Don't use NSUserDefaults, that would be inappropriate
in your #interface...
#property (assign) BOOL freshAlert1;
#property (assign) BOOL freshAlert2;
then something like this... (assuming 'page is reloaded' equates to your viewController coming back onscreen)
- (void)viewDidAppear
{
self.freshAlert1 = YES;
self.freshAlert2 = YES;
}
if (([_rcdAtIan.text intValue]> 200) && self.freshAlert1) {
self.freshAlert1 = NO;
...
}
if (([_rcdAt5an.text intValue]> 40) && self.freshAlert2) {
self.freshAlert2 = NO;
...
}
What exactly do you mean by "once"? Once per app run, once per editing step?
Or maybe simply add two BOOL flags that you can reset whenever you want and simply to
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_rcdAtIan.text intValue]> 200 && !alert1shown) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
alert1shown = YES;
[alert show];
}
if ([_rcdAt5an.text intValue]> 40 && !alert2shown) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"my message" delegate:nil cancelButtonTitle: #"Ok" otherButtonTitles: nil];
alert2shown = YES;
[alert show];
}
}

UIAlertVIew in UIAlertView

-(IBAction) secondTwoSlotSettings: (id)sender{
UIAlertView *secondTwoSlotSettings = [[UIAlertView alloc] initWithTitle:#""
message:#""
delegate:self
cancelButtonTitle:#"キャンセル"
otherButtonTitles:#"2スロット カメラ",#"2スロット カメラロール", nil];
[secondTwoSlotSettings show];
}
-(IBAction) firstTwoSlotSettings: (id)sender{
UIAlertView *firstTwoSlotSettingsMessage = [[UIAlertView alloc] initWithTitle:#""
message:#""
delegate:self
cancelButtonTitle:#"キャンセル"
otherButtonTitles:#"1スロット",#"2スロット", nil];
[firstTwoSlotSettingsMessage show];
}
-(IBAction) oneSlotSettings: (id)sender{
UIAlertView *oneSlotSettingsMessage = [[UIAlertView alloc] initWithTitle:#""
message:#""
delegate:self
cancelButtonTitle:#"キャンセル"
otherButtonTitles:#"カメラ",#"カメラロール", nil];
[oneSlotSettingsMessage show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"キャンセル"])
{
NSLog(#"キャンセル was selected.");
}
else if([title isEqualToString:#"はい"])
{
NSLog(#"はい was selected.");
}
else if([title isEqualToString:#"2スロット カメラ"])
{
NSLog(#"2スロット カメラ was selected.");
}
else if([title isEqualToString:#"1スロット"])
{
NSLog(#"1スロット was selected.");
}
else if([title isEqualToString:#"2スロット"])
{
NSLog(#"2スロット was selected.");
UIAlertView *oneSlotSettingsMessage = [[UIAlertView alloc] initWithTitle:#""
message:#""
delegate:self
cancelButtonTitle:#"キャンセル"
otherButtonTitles:#"2スロット カメラ",#"2スロット カメラロール", nil];
[oneSlotSettingsMessage show];
}
else if([title isEqualToString:#"カメラ"])
{
NSLog(#"カメラ was selected.");
}
else if ([title isEqualToString:#"カメラロール"])
{
NSLog(#"カメラロール was selected.");
}
Here is my code:
I was only able to show the firstTwoSlotSettings and oneSlotSettings. but when I try to show the secondTwoSlotSettings it vanish.
No It is not possible with Apple's UIAlertView. When you present an alertView ,it will come modal to all other views and dismiss any other Alerts already present in the screen.
One thing you can do is to create a custom View as your alert and animates its present/dismiss action? Then you have the control to do whatever you want..

Resources