I have a delegate, which recives a message to delete a item with that item as an argument.
I want to show a confirmation AlertView, and then, if the users press Yes, i want to delete it.
So, what I have is
The delegate method that gets called:
- (void) deleteRecording:aRecording(Recording*)aRecording {
NSLog(#"Cancel recording extended view");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: NSLocalizedString(#"Cancel recording",nil)
message: NSLocalizedString(#"Are you sure you want to cancel the recording?",nil)
delegate: self
cancelButtonTitle: NSLocalizedString(#"No",nil)
otherButtonTitles: NSLocalizedString(#"Yes",nil), nil];
[alert show];
[alert release];
}
And the method thats checks which button has been pressed:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
{
NSLog(#"Delete was cancelled by the user");
}
break;
case 1:
{
NSLog(#"Delete deleted by user");
}
}
}
So, my question is, how can i send the aRecording parameter from the first method to the second?
Thanks a lot
Store that variable in a member variable (easiest solution)
If you are only passing an int variable, you can set AlertView tag
property.
myAlertView.tag = YOUR_INT;
According to the documentation,
Note : The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is
private
and must not be modified.
So please use the 3rd method only if you are not intending to submit
app to app store. Thanks user soemarko ridwan for the tip.
For passing complex objects, subclass UIAlertView, add an object
property
#interface CustomAlertView : UIAlertView
#property (nonatomic, retain) id object;
#end
#implementation CustomAlertView
#synthesize object;
- (void)dealloc {
[object release];
[super dealloc];
}
#end
When you create AlertView
CustomAlertView *alert = [[CustomAlertView alloc]
initWithTitle: NSLocalizedString(#"Cancel recording",nil)
message: NSLocalizedString(#"Are you sure you want to cancel the recording?",nil)
delegate: self
cancelButtonTitle: NSLocalizedString(#"No",nil)
otherButtonTitles: NSLocalizedString(#"Yes",nil), nil];
[alert setObject:YOUR_OBJECT];
[alert show];
[alert release];
In the delegate
- (void)alertView:(TDAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
NSLog(#"%#", [alertView object]);
}
Related
So I have the following code and when the round is over it pops up with the following UIAlertView. Now when the user pushes the leaderboards button I want it to run the - (void) statement I have that displays the leaderboards. Please not that this is all inside of a sprite kit view controller. How should I do this?
Also I have my void statement in a different class, is there anyway to bring that over via an #import?
- (void) gameEnded
{
// indicate our game state as stopped
_gameState = STOPPED;
// create a message to let the user know their score
NSString *message = [NSString stringWithFormat:#"You scored %d this time", _score];
// show the message to the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Game over!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Leaderboards",nil];
[av show];
// reset the score tracker for the next game
_score = 0;
//reset playing area
[self removeAllBlocks];
[self addBlocks];
}
Here:
// show the message to the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Game over!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Leaderboards",nil];
You need to set the delegate to 'self', or another class that you want be handling the alert view events as its delegate. That class must conform to the UIAlertViewDelegate, for example:
#interface YourController : YourControllerSuperClass <UIAlertViewDelegate>
Then, Xcode will probably suggest you to implement:
– alertView:clickedButtonAtIndex:
As this is the method called by the alert view on its delegate when a button is pressed.
Here you'll receive a reference to your alert view and the index of the pressed button.
With this, you can find which action was performed.
For example:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
// In case there are more then one alert view and a reference to each of the alert views are kept.
if(alertView == self.avAlertView){
switch(buttonIndex){
// Your button's cases!
}
}
}
Your current Controller should implement UIAlertViewDelegate, and call the method alertView:clickedButtonAtIndex: with the index of your leaderboard button.
Your CustomController.h:
#import <UIKit/UIKit.h>
#interface AdsEventViewController : UITabBarController<UIAlertViewDelegate>
#end
Your CustomController.m:
[...]
- (void) gameEnded
{
// indicate our game state as stopped
_gameState = STOPPED;
// create a message to let the user know their score
NSString *message = [NSString stringWithFormat:#"You scored %d this time", _score];
// show the message to the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Game over!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Leaderboards",nil];
[av show];
// reset the score tracker for the next game
_score = 0;
//reset playing area
[self removeAllBlocks];
[self addBlocks];
}
[...]
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex == _LEADERBOARD_BUTTON_INDEX_ ){
// leaderboard method
}
}
I try to have the delegate method called but it isn't. What should I change in my code? Thank you.
I tried to add in Class1.m:
+(void)popupAlert:(NSString*)msg tag:(NSInteger)tag{
Class1 *c= [[Class1 alloc]init];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:msg
delegate:c (I also tried c.self)
cancelButtonTitle:...
otherButtonTitles:...,nil];
alert.tag=tag;
[alert show];
}
I try to set alertview delegate to make this delegate method called.
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
Here is what I'm doing:
Class1.h:
+(void)popupAlert:(NSString*)msg tag:(NSInteger)tag;
Class1.m:
+(void)popupAlert:(NSString*)msg tag:(NSInteger)tag{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:msg
delegate:self
cancelButtonTitle:...
otherButtonTitles:...,nil];
alert.tag=tag;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
//some coding
}
Class2.m:
-(void)func1{
[Class1 popupAlert:#"blah blah" tag:0];
}
It seems c gets dealloced right after [alert show]; because there are no strong reference pointing to this object afterwards and the delegate becomes nil;
In other example you should turn instance method
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
to class method:
+(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
Rethink your architecture.
You are creating the alert in a class method. (That is indicated by the leading + instead of -). Within that self is a reference to the class, not the object.
alertView:didDismissWithButtonIndex: is an instance method. I am not even sure that you could apply a delegate protocol to the class instead of the instances. But if you can, then your delegate method would have to be a class method too.
+(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
Well, I am just thinking of that and DO NOT PROMISE that it works that way.
If I were you I'd go for a singleton pattern and use instance methods to throw the alert and to respond to the delegate protocol.
Anyway, I am wondering which warning xcode displays on delegate:self and why you are not telling us about the warning. Warnings are there for a reason.
Alertview delegate property is week reference.
So once you finished the +(void)popupAlert:(NSString*)msg tag:(NSInteger)tag method then all local variables on Stack will removed from memory.
means destroyed. So even you set the delegate there it wont work.
#property(nonatomic,assign) id /*<UIAlertViewDelegate>*/ delegate;
So you should do like this
-(void)func1{
Class1 *class1 = [[Class1 alloc] init];
[Class1 popupAlert:#"blah blah" tag:0 withDelegate:class1];
}
+(void)popupAlert:(NSString*)msg tag:(NSInteger)tag withDelegate:(id)delegateOfAlert]{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:msg
delegate:delegateOfAlert
cancelButtonTitle:...
otherButtonTitles:...,nil];
alert.tag=tag;
[alert show];
}
I have a UIAlertView with UIAlertViewStyleSecureTextInput. When the user taps "Login" and the password is correct, it will push the next ViewController. If the password is incorrect, it displays another UIAlertView prompting a single "Dismiss" button. What I am trying to do is when the user taps the return key, the "Login" button will be triggered. As it sits now, when the return key is pressed the alert just dismisses, regardless if the password is correct or not. Maybe there is a more logical solution than what I have attempted? Sorry if the title is a little confusing, I don't know how else to explain it. Any help is greatly appreciated. Thanks.
I have declared the first alert in my .h file, and conformed to the UIAlertViewDelegate and UITextFieldDelegate:
#interface EndViewController : UIViewController <UIAlertViewDelegate, UITextFieldDelegate>
#property (retain, strong) UIAlertView *loginRequiredMsg;
Method for the "Login" alert:
- (IBAction)resultsBtnPressed:(UIButton *)sender {
self.loginRequiredMsg = [[UIAlertView alloc]initWithTitle:#"Login Required"
message:#"Please enter the admin password"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Login", nil];
self.loginRequiredMsg.alertViewStyle = UIAlertViewStyleSecureTextInput;
[self.loginRequiredMsg textFieldAtIndex:0].delegate = self;
[self.loginRequiredMsg show];
}
Method for dismissing the keyboard when return key is tapped (I think I need to somehow call the next alert here if the password is incorrect, as currently it just dismisses the alert):
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Dismiss keyboard when return key is pressed
[self.loginRequiredMsg dismissWithClickedButtonIndex:self.loginRequiredMsg.firstOtherButtonIndex animated:YES];
return YES;
}
And finally the method containing the outcome of the password entered:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Login"]) {
UITextField *password = [alertView textFieldAtIndex:0];
// Basic login authentication
if ([password.text isEqualToString:#"admin"]) {
// Allocate & initialise ViewController
ResultsViewController *Results = [[ResultsViewController alloc]initWithNibName:#"ResultsViewController" bundle:nil];
// Push next ViewController
[self.navigationController pushViewController:Results animated:YES];
NSLog(#"Show results");
} else {
UIAlertView *errorMsg = [[UIAlertView alloc]initWithTitle:#"Error"
message:#"Admin password is incorrect. Please try again."
delegate:self
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil];
[errorMsg show];
}
}
}
As discussed in the comments, you need to implement alertView:didDismissWithButtonIndex: which tells you when the alert view has been dismissed. When you tap the return key, it calls that method with the index of the OK button.
In my application i want alertview in many views.So what i did is just wrote a single alertview in a utility class and use it everywhere.This is working fine.
I even tried by setting <UIAlertViewDelegate> but in vain.
Utility Class
#interface SSUtility: NSObject<UIAlertViewDelegate> {
}
+(void)showAllert;
#end
#implementation SSUtility
+(void)showAllert{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"gotoappAppstore",#"") message:#"" delegate:self cancelButtonTitle:NSLocalizedString(#"Ok",#"") otherButtonTitles:nil];
[alert show];
[alert release];
}
#end
Now from my view
-(void)pressButton{
[SSutility showAllert]
}
Now i want to give a button action for alert view click and call a method on that button action.
So im stuck with,in which class i want to implement this method.I tried it in utility class and viewc controller but the method is not getting triggered when "ok" button is pressed.
-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
Can anyone please help me on this?
Thanks in advance.
You wire the alert view button response method by setting your alert view object delegate usually to the owner object and implementing the – alertView:clickedButtonAtIndex: method.
You need 4 parts in your code:
instantiate your UIAlertView object
send show message to your UIAlertView object
set delegate
implement the delegate method
Example:
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:#"myTitle" message:#"myMessage" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitle:#"Another button"];
[myAlertView setDelegate:self];
[myAlertView show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) //index 0 is cancel, I believe
{
// code for handling cancel tap in your alert view
}
else if (buttonIndex == 1)
{
// code for handling button with index 1
}
}
I would recommend you get more familiar with how delegates work. This'll come back again a lot.
You set delegate:nil in your UIAlertView's init.
You should set to delegate:self, like this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"gotoappAppstore",#"") message:#"" delegate:self cancelButtonTitle:NSLocalizedString(#"Ok",#"") otherButtonTitles:nil];
in order to use the delegate in the same class (a.k.a. self).
As a sidenote, if you use Automatic Reference Counting (ARC), you do not need [alert release] (your Xcode compiler should warn you about this)
I've created a UIAlertView and now I want to check which button the user presses.
My code is:
- (IBAction)button1 {
{
UIAlertView *alert1 = [[UIAlertView alloc] init];
[alert1 setTitle:#"Hello"];
[alert1 setMessage:#"Do you like smoking?"];
[alert1 addButtonWithTitle:#"Yes"];
[alert1 addButtonWithTitle:#"No"];
[alert1 show];
}
}
How can I check it with if-else statement?
You must set the delegate of your UIAlertView to the class that will handle the callbacks from the UIAlertView itself
E.g.
[alert1 setDelegate:self];
Where self is your current UIViewController that implements the protocol <UIAlertViewDelegate>.
When the user taps a button, the UIAlertView will call back to whatever object you set as the delegate, in my example we are using the UIViewController that created the UIAlertView. Once we get the callback, we can check which button index has been tapped and act accordingly. This is a basic delegation pattern that is used throughout iOS development, especially UIKit.
Example
#interface MyViewController : UIViewController() <UIAlertViewDelegate>
#end
#implementation MyViewController
- (IBAction)button1 {
{
UIAlertView *alert1 = [[UIAlertView alloc] init];
[alert1 setTitle:#"Hello"];
[alert1 setMessage:#"Do you like smoking?"];
[alert1 addButtonWithTitle:#"Yes"];
[alert1 addButtonWithTitle:#"No"];
[alert1 setDelegate:self];
[alert1 show];
}
}
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// Handle interaction
switch (buttonIndex)
{
case 0:
NSLog(#"Yes was pressed");
break;
case 1:
NSLog(#"No was pressed");
break;
}
}
#end
It is very important you specify in the header file, or class interface extension that your class implements the <UIAlertViewDelegate>.
I recommend you see the UIAlertViewDelegate Protocol Reference for more information, and you can follow this approach for many other UIKit components.
Implement UIAlertViewDelegate protocol in your view controller, set it as a delegate to the UIAlertView, and wait for the alertView:clickedButtonAtIndex: event, like this:
#interface MyViewController : UIViewController <UIAlertViewDelegate>
-(void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex;
#end
#implementation MyViewController
-(void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"Button %d clicked...", (int)buttonIndex);
}
#end
Change the code that displays the alert view as follows:
UIAlertView *alert1 = [[UIAlertView alloc] init];
[alert1 setTitle:#"Hello"];
[alert1 setMessage:#"Do you like smoking?"];
[alert1 addButtonWithTitle:#"Yes"];
[alert1 addButtonWithTitle:#"No"];
alert1.delegate = self; // <<== Add this line
[alert1 show];
Adding on to the answer by Jeff, I think that you have to enable the other button in order to place your logic when the button is clicked.
In order to creating the button with your code:
- (IBAction)button1
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello"
message:#"Do you like smoking?"
delegate:self
cancelButtonTitle:#"Yes"
otherButtonTitles:#"No", nil];
[alert show];
}
But before knowing which button is clicked, you have to enable the first other button, by calling this delegate method:
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
return YES;
}
This will enable the NO button that you have created. Then, you will be able to do some logic with the clickedButtonAtIndex method, which I suppose you will be doing.
Implement the UIAlertView delegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
// i love smoking!
} else if (buttonIndex == 1) {
// i hate smoking!
}
}
Be sure to declare the UIAlertViewDelegate in your header class.
Make sure that the alertViewShouldEnableFirstOtherButton: method returns YES, if not you will not be able to put in your logic for when the button is pressed.
Hope this helps! :)
The best thing you can do is make the class that presents your alert view conform to the UIAlertViewDelegate protocol and implement the method –alertView:clickedButtonAtIndex:. That way you'll know what button was clicked.
Hope this helps!