27

The UIAlertviewDelegate protocol has several optional methods including:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

This would seem to suggest that not all button clicks actually dismiss the alert view. However I see no way of configuring the alert view to NOT automatically dismiss with any button press.

Do I have to create a subclass to accomplish this?

Why would the UIAlertViewDelegate Protocol have:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex

AND

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

If it didn't optionally support not dismissing the alert view with each button click?

Brief Aside: I realize what UIAlertView was designed for. But my purpose is to allow the user to copy some text to the paste board before the app exits (which happens automatically when the alert view is dismissed.

Corey Floyd
  • 25,929
  • 31
  • 126
  • 154

5 Answers5

28

Yes. Subclass UIAlertView and then overload -dismissWithClickedButtonIndex:animated:, e.g.

@implementation MyAlertView 
-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {
   if (buttonIndex should not dismiss the alert)
      return;
   [super dismissWithClickedButtonIndex:buttonIndex animated:animated];
}
@end

Unofficially you can define a

-(void)alertSheet:(UIAlertSheet*)sheet buttonClicked:(id)button;

method to the delegate which will make it bypass -dismissWithClickedButtonIndex:animated:, but it's undocumented, so I don't know whether it's suitable for you.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
3

willPresentAlertView:, didPresentAlertView:, alertView:willDismissWithButtonIndex:, and alertView:didDismissWithButtonIndex: are for tracking the start and end of UIAlertView's animations.

Applications that don't need to track UIAlertView's animations can simply use alertView:clickedButtonAtIndex:. The docs for that method say "the receiver is automatically dismissed after this method is invoked."

Darren
  • 25,520
  • 5
  • 61
  • 71
  • Thanks, I missed that last piece of text in the docs. Still seems like overkill to have that extra method, since it essentially the same as willPresentAlertView… – Corey Floyd Jan 12 '10 at 23:13
  • @Darren: Thanks and lot in ios7 alertView:willDismissWithButtonIndex: this method call twice. but your solution save my day.. – TamilKing Feb 20 '14 at 08:40
3

In my opinion: There's no reason to keep alertView. Even if you wanna keep it, just think about "re-show" it, by keeping a reference, then call [alertView show] ==> NO NEED TO SUBCLASS ANYTHING. Good news, huh?

samthui7
  • 923
  • 2
  • 12
  • 11
1

WARNING

From some sources I have heard that few app have got rejected following this process. I was lucky in my case during iOS6 so I am showing code here. Use on your own risk :-/

Subclassing is the best way. Create a bool flag for alert should stay or not.

This is the Subclass of UIAlertView

//
//  UICustomAlertView.h
//

#import <UIKit/UIKit.h>

@interface UICustomAlertView : UIAlertView
{
    
}
@property(nonatomic, assign) BOOL dontDisppear;
@end

//
//  UICustomAlertView.m
//

#import "UICustomAlertView.h"

@implementation UICustomAlertView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {

    if(self.dontDisppear)
        return;
    [super dismissWithClickedButtonIndex:buttonIndex animated:animated];
}
@end

And this is how I used it into my code

if(![txtUsername.text isEqualToString:@"admin"] && ![txtPassword.text isEqualToString:@"admin"])
{
     alertLogin.dontDisppear = YES;
     alertLogin.message = NSLocalizedString(@"my_alert", nil);
}
else
{
     alertLogin.dontDisppear = NO;
     // proceed
}
Community
  • 1
  • 1
Vaibhav Saran
  • 12,848
  • 3
  • 65
  • 75
  • I have given a -1, the reason being because of `"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"` in https://developer.apple.com/library/ios/documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html so implementing your way would be going against the Apple Documentation and Review process so would get their app rejected. This has been the way for a few years now so at the time of you answering this will have been an incorrect answer. – Popeye May 29 '14 at 07:49
  • May be but my app approved last year (iOS 6). – Vaibhav Saran May 30 '14 at 05:33
  • Sorry but it doesn't mean it is right. I submitted an app before I knew about this as well and it got through the initial review process then was rejected when I submitted an update. The Apple review team are only human they can miss things. I know though they are being more strict with iOS 7 though. However my -1 was purely because this answer goes against the Apple documentation and you don't warn of it. If you warn of this I will happily remove my -1 – Popeye May 30 '14 at 06:53
  • 1
    I'm happy with that I have removed my -1 – Popeye May 30 '14 at 09:53
1
#import "MLAlertView.h"

@implementation MLAlertView


-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {
}

-(void)dismissNow:(NSInteger)buttonIndex  {
     [super dismissWithClickedButtonIndex:buttonIndex animated:YES];
}
Gank
  • 4,507
  • 4
  • 49
  • 45