syedfa
syedfa

Reputation: 2819

Can an AlertView be timed out in an iOS app?

I want to know if it is possible for an AlertView to time out if it has been visible on the screen for a certain period of time without receiving any acknowledgement from the user, and if so, how? Is there a way for the AlertView object be linked with an NSTimer object?

My basic AlertView code is the following:

- (IBAction)showMessage:(id)sender {
    UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Hello World!"
                                                      message:@"This is your first UIAlertview message."
                                                     delegate:nil
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil];
    [message show];
}

Upvotes: 1

Views: 2741

Answers (5)

jowie
jowie

Reputation: 8068

You could create a category for UIAlertView and add an observer which listens out and if it is triggered, removes itself:

@implementation UIAlertView (Cancellable)

+ (instancetype)cancellableAlertViewWithTitle:(NSString *)title
                                      message:(NSString *)message
                                     delegate:(id)delegate
                            cancelButtonTitle:(NSString *)cancelButtonTitle
                            otherButtonTitles:(NSString *)otherButtonTitles, ...
{
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
                                                        message:message
                                                       delegate:delegate
                                              cancelButtonTitle:cancelButtonTitle
                                              otherButtonTitles:nil];
    if (otherButtonTitles != nil)
    {
        va_list args;
        va_start(args, otherButtonTitles);
        for (NSString *buttonTitle = otherButtonTitles; buttonTitle != nil; buttonTitle = va_arg(args, NSString*))
        {
            [alertView addButtonWithTitle:buttonTitle];
        }
        va_end(args);
    }

    [[NSNotificationCenter defaultCenter] addObserver:alertView selector:@selector(removeAlertView:) name:@"AlertsShouldBeCancelledNotification" object:nil];

    return alertView;
}

- (void)removeAlertView:(NSNotification *)notification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self dismissWithClickedButtonIndex:-1 animated:YES];
}

@end

Then you could create an NSTimer in your main class and have it trigger the notification when the selector is called.

Upvotes: 1

Iain Delaney
Iain Delaney

Reputation: 562

Take a look at this answer: dismissing a UIAlertView programmatically . Using performSelector:withObject:afterDelay: is much more elegant than building and tearing down a timer, in my opinion.

Upvotes: 0

nizx
nizx

Reputation: 690

This is how I implemented in one of my apps

Inside the @interface declare your objects so you can keep track of them and add the if required

@property (nonatomic, strong) UIAlertView *myAlert;
@property (nonatomic, weak) NSTimer *myTimer;

In your code where you need to launch the alert add the following

self.myAlert = [[UIAlertView alloc]initWithTitle:@"TEST" message:@"TEST" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(cancelAlert) userInfo:nil repeats:NO];
[self.myAlert show];

Somewhere in your code add next function to dismiss the alert and invalidate the NSTimer

- (void)cancelAlert {
[self.myAlert dismissWithClickedButtonIndex:-1 animated:YES];
}

Also remember to invalidate the timer if a button is touched.

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
[self.myTimer invalidate];
// Process pressed button
}

It may need some tweaks for your requirements.

Upvotes: 4

Max
Max

Reputation: 587

Use an NSTimer to call dismissWithClickedButtonIndex:animated: and invalidate it if the user clicks in time. Using dispatch_after risks sending the message to a released instance if the user has dismissed it already.

Upvotes: 0

Matthias Bauch
Matthias Bauch

Reputation: 90117

Yes. Use dismissWithClickedButtonIndex:animated:

For example with a dispatch_after block, like this:

int64_t delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [message dismissWithClickedButtonIndex:message.cancelButtonIndex animated:YES];
});

If you want to use a NSTimer just save the UIAlertView in an instance variable so you can access it from within the timer method.

Upvotes: 1

Related Questions