Detecting button pressed when there are multiple alert views - iphone

I have multiple alert views in one view, and I use this code to detect which button was pressed:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if ([title isEqualToString:#"OK"]) {
//for one alert view
[passCode becomeFirstResponder];
} else if ([title isEqualToString:#" OK "]) {
//for another alert view, had to change "OK" to " OK "
[passCodeConfirm becomeFirstResponder];
}
}
Now since there are multiple alert views in one view that do different things, I have to trick the user into thinking "OK" and " OK " are the same thing. It works and looks fine, but it feels kind of messy. Surely there is another way to do this, such as making this specific to an alert view, and then making it specific to another. Do you know how I would do this? Thanks!

It would be more technical as well better that set unique tag for separate UIAlertView and identify it and access in its delegate method.
For example,
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Message" message:#"Are You Sure you want to Update?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
[alert setTag:1];
[alert show];
[alert release];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(alertView.tag == 1)
{
// set your logic
}
}

Use tag property to uniquely identify each of the alertview u create.
Like this
myAlertView.tag = 1
Then in the clickedButtonAtIndex delegate method check which alertview's button was clicked using this tag property ,
if(alertView.tag==1)

I wouldn't use the titles to distinguish between the buttons. You'll run into problems when your app is localized or you decide to change the button titles, but forget to update them everywhere. Use the button indexes instead or if you only have one button in addition to a cancel button, use the cancelButtonIndex property of UIAlertView.
To distinguish between multiple alert views, you could use their tag property.

In your view, add a property for each alert view.
UIAlertView *myAlertType1;
UIAlertView *myAlertType2;
#property (nonatomic, retain) UIAlertView *myAlertType1;
#property (nonatomic, retain) UIAlertView *myAlertType2;
Create your alert using these properties
self.myAlertType1 = [[[UIAlertView alloc] initWithTitle: ... etc] autorelease];
[self.myAlertType1 show];
Then in your delegate method:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView == myAlertType1) {
// check the button types and add behaviour for this type of alert
} else if (alertView == myAlertType2 {
// check the button types and add behaviour for the second type of alert
}
}
Edit: Although the above works, iApple's suggestion of using the tag seems cleaner/simpler.

//in your .h file
UIAlertView* alert1;
UIAlertView* alert2;
//in your .m file
// when you are showing your alerts, use
[alert1 show]; //or
[alert2 show];
//and just check your alertview in the below method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(alertView == alert1)
{
//check its buttons
}
else //check other alert's btns
}

Related

How to handle sender tag in Alert View

I am very new to iOS development. I have the following method done by another developer
-(IBAction)btnDelete:(UIButton *)sender
{
indexOfBlockedFriend=sender.tag-50;
[self deleteFriend];
}
I want to show an alert view before the delete action is performed. How do I do that.
To handle AlertView button click, you have to conform to UIAlertViewDelegate protocol.
in your.h
#interface YourViewController:UIViewController<UIAlertViewDelegate>{
.......
.......
}
Then implement UIAlertViewDelegate protocol methods,
in your.m
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0){
//cancel clicked ...do your action
}else if (buttonIndex == 1){
//reset clicked
}
}
With the UIAlertView class
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello World" message:#"Hello" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
If you want to have more than one option you will need to become the delegate for the alert to get a callback for which button was touched. Delegation is a concept of Object Oriented Programming (OOP) that you will have to become familiar with.
EDIT:
You may be interested in block-based UIAlertViews. The one that I use in a lot of projects is called UIAlertView+MKBlockAdditions. It contains easy methods for handling all the alert delegate logic in a block handled by the alert.

Showing UIActionSheet over UIAlertView

For a specific server notification I am supposed to show an UIActionSheet. But problem here is when that event comes, at the same time if any UIAlertView already showing on any view controller, it make the UIActionSheet disabled( After pressed ok for alert view I am not able to select anything on view controller , view got disabled because of UIActionSheet). Anyone faced this kind of problem, Any idea how to solve it?
I have tried by dismissing alert view before showing action sheet, however which alert view do I need to dismiss as I have many alert view in many controller. All are local to that controllers. How to solve this problem.
Note:
Same problem won't come for iPod, as it wont allow to click ok before responding to UIActionSheet.
Take a Global Alert view named it as activeAlertView. Now when you show a alert view please check that alert view and then show and assign. Like
declare a property in .h and synthesize it
#property (nonatomic, retain) UIAlertView *activeAlertView;
then use the below code when try to show an alert.
if(self.activeAlertView){
[self.activeAlertView dismissWithClickedButtonIndex:0 animated:YES];
}
UIAlertView *localAlert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Your message" delegate:nil cancelButtonTitle:#"cancel" otherButtonTitles:nil, nil ];
[localAlert show];
self.activeAlertView = localAlert;
[localAlert release];
this way your activeAlertview will keep the current aler view's reference and before show the actionSheet dismiss the alert view.
For Identified which alert-view you must set Tag or alert-view.
Ex:-
alertviewName.tag=1;
Then you can check is there alert-view Open in Particular view-controller sub-views use bellow code like:-
- (BOOL) doesAlertViewExist {
for (UIView* view in yuorviewcontroller.view.subviews) {
BOOL alert = [view isKindOfClass:[UIAlertView class]];
if (alert)
{
return YES;
}
}
return NO;
}
After this method called you get BOOL value YES or NO If Yes then dismiss it using UIAlertview's Delegate:-
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
and put your Actionsheet appear code into didDismissWithButtonIndex method.
When the message comes, first check if there is an alert view.
Show the action sheet after the alert view is dismissed. In didDismiss... you can check a BOOL flag if you now have to show the action sheet or not.
In this case, you should use
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
method rather than,
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
so your code wil be:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
UIActionSheet *actionSheet = ...
[actionSheet showFromTabBar:self.tabBarController.tabBar];
}
}
Thanks
try this:
for (UIWindow* w in [UIApplication sharedApplication].windows)
{
for (NSObject* obj in w.subviews)
{
if ([obj isKindOfClass:[UIAlertView class]])
{
[(UIAlertView*)obj dismissWithClickedButtonIndex:[(UIAlertView*)obj
cancelButtonIndex] animated:YES];
}
}
}

How to distinguish between UIAlertView Cancel and UIAlertViewStyleSecureTextInput's TextView Return?

I have created a UIAlertView
alert = [[UIAlertView alloc] initWithTitle:#"Test"
message:#"Working"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert setAlertViewStyle:UIAlertViewStyleSecureTextInput];
alert.tag = kAlertTypePIN;
UITextField *textField = [alert textFieldAtIndex:0];
textField.delegate = self;
If I press Retun key in UIAlertView textfield it works fine, it calls:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
and then
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"didDismissWithButtonIndex");
// If no text or wrong text show alert again otherwise normal actions
}
But if I press the cancel button, it 1st calls textFieldDidEndEditing which in turn calls the alert delegate. And again it calls the alert delegate method by itself.
So alert to be displayed is not getting shown and keyboard starts to pop up and goes back. So no alert is being shown in case when its to be shown.
If any doubts in the flow, please ask me.
How can I rectify the issue?
unset the delegate of the textField in alertView:willDismissWithButtonIndex:
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
UITextField *textField = [alert textFieldAtIndex:0];
textField.delegate = nil;
}
When the alert is dismissed the textField will end editing, and afterwards it will call the textFieldDidEndEditing: delegate method.
If you set the delegate to nil before the dismissal starts, the delegate method can't be called.
Besides that, a better design would be to have a cancel button "Cancel", and an other button "Submit". When the textField ends you dismiss the alert with "Submit", and not "Cancel".
You simply want to hide UIAlertiView on cancel click?
Then if your cancel buttonindex is 1 then:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
if(buttonIndex == 1) {
[[alert textFieldAtIndex:0] resignFirstResponder];
}
}
try this condition.. as you dont want alert to be gone when Pin is not there...
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if([textField.text length]!=0)
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
If you want to hide UIAlertiView on "Cancel" button click then just simply add this code to clickedButtonAtIndex:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1)
{
[[alert textFieldAtIndex:0] resignFirstResponder];
}
}
Try this
Add UIAlertView following delegate method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
{
[[alert textFieldAtIndex:0] resignFirstResponder];
}

Multiple alertviews in a single view?

I have an Iphone application in which when i am pressing a button it shows an alertview to chose the background.whichever background user is chosing will be played as the background of the audio clips.But now i need to add another alert before i am showing this alert for giving some warning.after that only i need to pop the second one.but i was done that chosing alert in the didappear of that viewcontroller and set it as a Uialertview delegate.and on the button actions i was doing different actions.Can anybody help me on achieving this?
proAlertView *loginav1=[[proAlertView alloc] initWithTitle:#"title" message:#"Choose a Background to play with this program?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Field",#"Beach", #"Stars",nil];
[loginav1 setBackgroundColor:[UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] withStrokeColor:[UIColor colorWithHue:0.625 saturation:0.0 brightness:0.8 alpha:0.8]];
[loginav1 show];
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
//[self play];
//moviePlayer.scalingMode=MPMovieScalingModeAspectFill;
if(actionSheet.tag==123)
{
[self backButtonPressed];
}
}
else if (buttonIndex == 1)
{
videoFile = [[NSBundle mainBundle] pathForResource:#"video-track" ofType:#"mp4"];
[self play];
moviePlayer.scalingMode=MPMovieScalingModeAspectFill;
}
how can i include another alert before this is my question?
Initialize first Alertview
UIAlertView *al1 = [[UIAlertView alloc] initWithTitle:#"Warning!" message:#"Warning Msg!!!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
al1.tag=1;
al1.delegate=self;
[al1 show];
Implement Delegate method
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(alertView.tag==1){
// implement button events for first Alertview
if(buttonIndex==1){
//First button clicked of first Alertview
UIAlertView *al2 = [[UIAlertView alloc] initWithTitle:#"Choose BG" message:#"Choose BG?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"1",#"2",#"3", nil];
al2.tag=2;
al2.delegate=self;
[al2 show];
}
}
if(alertView.tag==2){
// implement button events for second Alertview
if(buttonIndex==1){
// First button clicked second Alertview.
}
}
}
Controller Class header
#interface ViewController : UIViewController<UIAlertViewDelegate>{
}
Hope this will fulfill your need !
You can do like this, first display warning message in alertview and when user click OK in alertview then in alertview delegate method write code to display second alertview where user can choose background.

UIAlertViewStylePlainTextInput - Program continues without waiting for text input from user

I'm sort of stuck on a UIAlertViewStylePlainTextInput. (My code is too long to post here, but this is the part where the problem exists.) It all sort of works, but the program doesn't wait until the user enters the information before continuing. The "editName" button doesn't change the display in the code below, but the updateDisplay button works fine (if you've pressed the "editName" button before you pressed "updateDisplay"). How can I get everything to sort of halt until the user enters the info (or cancels). Or is there some other lead that will take me where I need to go. (I've been toying with putting the rest of the code in the -(void) alertView, but that just doesn't seem to be the correct way of doing it).
Thanks in advance.
#import "HSTestViewController.h"
#implementation HSTestViewController
#synthesize display;
NSString *newName;
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
newName = [[alertView textFieldAtIndex:0] text];
}
}
- (void) getNewName;
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"You made the High Score List"
message:#"Please enter your name"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
- (IBAction)editName:(id)sender
{
[self getNewName];
newName = display.text;
}
- (IBAction)updateDisplay:(id)sender
{
display.text = newName;
}
#end
Add UIAlertViewDelegate to the class. And implement the below delegate method.
OK button index value will be 1 in your case.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex)
{
// call the method or the stuff which you need to perform on click of "OK" button.
}
}
Hope this helps.