Handling alert buttons when your view has more than 1 alert - iphone

-(void)alertOKCancelAction
{
// open a alert with an OK and cancel button
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Return Home" message:#"Are
you sure you want to return to the menu?" delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
-(void)alertConnectionLost
{
// open a alert with an OK and cancel button
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Lost"
message:#"The connection to the other device has been lost" delegate:self
cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
}
else
{
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
}
As you can see above, I have 2 alerts. But they both call the same method to handle there key presses. How can I tell which alert is currently alive and respond to the keypresses differently depending on which alert is up?

Use: [alert setTag:1]; and [alert setTag:2]; respectively
then you can do:
if([actionSheet tag] == 1){
//do thing for first alert view
}
else if([actionSheet tag] == 2){
//do something for second alert view
}

Related

Restore button for in-app purchase - is it the same as buying again?

I have written some code for a restore button;
-(IBAction)restore:(id)sender
{
[[MKStoreManager sharedManager]buyFeature];
}
-(void)productPurchased
{
for (UIView *view in self.view.subviews)
{
if (view.tag==2000)
{
[view removeFromSuperview];
}
}
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Thank you" message:#"Your restore was successful." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
// error restore
- (void)failed
{
for (UIView *view in self.view.subviews)
{
if (view.tag==2000)
{
[view removeFromSuperview];
}
}
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Error" message:#"Your restore has failed." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
But it prompts the user to 'buy' when they press it? Is this correct? I know essentially the same thing is happening as it is not going to charge them again, but I don't want to submit this code to apple only for them to reject it on the fact it doesn't make it clear enough?
Or have I done the code incorrectly?
Your help would be great appreciated,
Regards,
Agnelli
I think you want to call the method restorePreviousTransactionsOnComplete:onError:, not buyFeature.

How to run a method from a UIAlertView

I want to have this method [User logOut]; run when a user touches the Log Me out button in the following UIAlertView.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Logged in!" message:#"Logged in to App!" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:#"Log me out", nil];
[alert show];
[alert release];
how would I go about doing that? The "Okay" works for the cancel button. I just need the other button/method to work.
thanks for any help
You can do something like;
- (void)AlertConfirm
{
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"Confirm"];
[alert setMessage:#"Log out?"];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Yes"];
[alert addButtonWithTitle:#"No"];
[alert show];
[alert release];
}
And
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
// Yes, do something
}
else if (buttonIndex == 1)
{
// No
}
}
Good luck,
Nathan
You need to use the UIAlertView delegate method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
Make sure you set yourself as the delegate of your alertView.
Set the alert view's delegate to be self, and in your .h add
The following delegate method will be called when a button is pressed:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
Then you can see what button was pressed by doing something like:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ((alertView == alert) && (buttonIndex == 0))
NSLog(#"alert's \"Okay\" button was pressed");
else
NSLog(#"alert's \"Log Out" button was pressed");
}
Set your view controller to be the delegate of the UIAlertView:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Logged in!" message:#"Logged in to App!" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:#"Log me out", nil];
alert.delegate = self;
[alert show];
[alert release];
Then handle in the delegate callback:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == alertView.cancelButtonIndex) {
// Cancelled
return;
}
// Log them out
}
Note the test (buttonIndex == alertView.cancelButtonIndex). This is better form than checking an absolute value for the button index.

How to add Cancel button between two other buttons (stacked) in UIAlertView (iOS)

I am trying to create a UIAlertView with three buttons (which will be stacked). I would like the Cancel button to be in the middle, between the two other buttons. I have tried setting the cancelButtonIndex to 1, but if there are two other buttons, it simply places them at indexes 0 and 1. I know I could just change the names of the buttons, but I want the darker blue formatting of the cancel button.
EDIT: **
Please note - I know how to get the three buttons with the titles in the correct order, but only if all three buttons essentially look like 'other' buttons; I want the cancel button to have the cancel button dark blue background so that it will look like a regular cancel button.
**
I've tried
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:button1Title,button2Title,nil] autorelease];
alert.cancelButtonIndex = 1;
[alert show];
and
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil] autorelease];
alert.cancelButtonIndex = 1;
[alert addButtonWithTitle:button1Title];
[alert addButtonWithTitle:button2Title];
[alert show];
and
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:addButtonWithTitle:button1Title,nil] autorelease];
alert.cancelButtonIndex = 1;
[alert addButtonWithTitle:button2Title];
[alert show];
to no avail. Is it even possible to accomplish what I am trying to do?
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:nil otherButtonTitles:nil] autorelease];
[alert addButtonWithTitle:button1Title];
[alert addButtonWithTitle:#"Cancel"];
[alert addButtonWithTitle:button2Title];
[alert show];
Might Help,
Cheers.
I have two ancillary points to this answer.
1) While, to the best of my knowledge, Apple has not rejected an app for reasonable modification of a UIAlertView; They have said that the view hierarchy of classes like UIAlertView should be considered private.
2) This question is a good example of why you should ask a question more about your end goal rather than the steps to get there. The only reason I know what this question is about is as a result of a comment left at my answer here.
Answer:
Because of your comment I know that you are looking to create a UIAlertView that has stacked buttons even when there are only 2 buttons.
I find the most logical place for code like this is in a category. Since generally the code needed to manipulate the alert-view needs to be around the show call, I created a category method I call instead of show and the method in turn calls show itself.
-(void)showWithButtonsStacked{
static NSString *tempButtonTitle = #"SomeUnlikelyToBeUsedTitle";
BOOL willAddFakeButton = (self.numberOfButtons == 2); // Button are only side by side when there's 2
if (willAddFakeButton){
self.clipsToBounds = YES;
[self addButtonWithTitle:tempButtonTitle]; // add temp button so the alertview will stack
}
BOOL hasCancelButton = (self.cancelButtonIndex != -1); // If there is a cancel button we don't want to cut it off
[self show];
if (willAddFakeButton){
UIButton *cancelButton = nil;
UIButton *tempButton = nil;
for (UIButton *button in self.subviews) {
if ([button isKindOfClass:[UIButton class]]){
if (hasCancelButton && [button.titleLabel.text isEqualToString:[self buttonTitleAtIndex:self.cancelButtonIndex]]){
cancelButton = button;
} else if ([button.titleLabel.text isEqualToString:tempButtonTitle]) {
tempButton = button;
}
}
}
if (hasCancelButton){ // move in cancel button
cancelButton.frame = tempButton.frame;
}
[tempButton removeFromSuperview];
// Find lowest button still visable.
CGRect lowestButtonFrame = CGRectZero;
for (UIButton *button in self.subviews) {
if ([button isKindOfClass:[UIButton class]]){
if (button.frame.origin.y > lowestButtonFrame.origin.y){
lowestButtonFrame = button.frame;
}
}
}
// determine new height of the alert view based on the lowest button frame
CGFloat newHeight = CGRectGetMaxY(lowestButtonFrame) + (lowestButtonFrame.origin.x * 1.5);
self.bounds = CGRectMake(0, 0, self.bounds.size.width, newHeight);
}
}
The way this method accomplishes it's goal is to add a temporary button to the alert-view to force the alert-view to stack the buttons, then it removes the temporary button and adjusts the height. Since it's a category method you use it simply by calling:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Test title" message:#"message" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alert showWithButtonsStacked];
This code results in an alert like this:
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:nil otherButtonTitles:nil] autorelease];
[alert addButtonWithTitle:button1Title];
[alert addButtonWithTitle:#"Cancel"];
[alert addButtonWithTitle:button2Title];
[alert setCancelButtonIndex:1]; // to make it look like cancel button
[alert show];
Set the cancel button to nil and just add it in the other buttons instead

Disable Alertview Programmatically

I want to display a activity indicator in AlertView with no buttons, I want to disable it when activity indicator stops animating.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
UIActivityIndicatorView *progress= [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125, 50, 30, 30)];
progress.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
[alert addSubview:progress];
[progress startAnimating];
[alert show];
[progress release];
Then to dismiss the alert view and spinner: (you'll need to make the alert view a member)
[alert dismissWithClickedButtonIndex:0 animated:YES];
[alert release];
Just call dismissWithClickedButtonIndex:animated: method for UIAlertView
[alertView dismissWithClickedButtonIndex:0 animated:YES];
Just call the:
[theAlertViewInstance dismissWithClickedButtonIndex: 0 animated:YES];
This should do, what you need.

UIAlertView not displaying the keyboard

I have UIAlertView which is being displayed upon the load of a view.
av = [[UIAlertView alloc]initWithTitle:#"New Password" message:#"please enter a new passward" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"done", nil];
av.alertViewStyle = UIAlertViewStyleSecureTextInput;
[av becomeFirstResponder];
[av show];
However the keyboard is not being display on the iPad or the simulator?
I have also tried
I just tried
[av becomeFirstResponder];
and also
UITextField *text = [alertView textFieldAtIndex:0];
[text becomeFirstResponder];
I just tried this piece of code and it logs that the textField is the first responder but still no keyboard.
if([[av textFieldAtIndex:0] isFirstResponder] == YES){
NSLog(#"av is the first responder.");
}
Making the alert into the first responder won't help. You need to make te text box inside the alert view into the first responder.
Edit:
You may need to call reloadInputViews (with or without the s, don't remember). Also double check that you're not changing the input views anywhere that might be breaking them.
Edit 2:
You might want to move the alert from viewDidLoad into viewDidAppear. I've seen problems with UI elements being updated/presented too early. This is one of those cases, I think.
To use
av = [[UIAlertView alloc]initWithTitle:#"New Password" message:#"please enter a new passward" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"done", nil];
av.tag=1;
av.alertViewStyle = UIAlertViewStyleSecureTextInput;
[av show];
and use this method.
- (void)alertView:(UIAlertView *)alertViews clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertViews.tag==1)
{
[textfieldname becomeFirstResponder];
}
}
this works
self.alertView = [[UIAlertView alloc]initWithTitle:#"Login" message:#"Please enter you mobile number" delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil];
self.alertView.alertViewStyle=UIAlertViewStylePlainTextInput;
[alertView show];
but not this
UIAlertView* alertView = [[UIAlertView alloc] init];
[alertView initWithTitle:...]
av = [[UIAlertView alloc]initWithTitle:#"New Password" message:#"please enter a new passward" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"done", nil];
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
CGAffineTransform Transform = CGAffineTransformMakeTranslation(0, 60);
[tf setBackgroundColor:[UIColor whiteColor]];
[av setTransform:Transform];
[av addSubview:tf];
[av show];
This works but you should be able to do this in IOS 5 using UIAlertViewStyleSecureTextInput??
I had the same issue, but my solution looks like it might not apply to original poster...
I had this code :
UIAlertView* alert = [[UIAlertView alloc] init];
[alert initWithTitle:...]
When run, no keyboard appeared.
I changed it to this, and keyboard now appears:
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:...];
Doing the init after alert was created seem to leave internal state of object as "this object doesn't need a keyboard!"