Reputation: 2819
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
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
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
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
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
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