问题
I'm trying to display a countdown in the title of a UIAlertController. I want to have something like "Your session is going to expire in X seconds". My thought process was to create an NSTimer and store the time in an NSString stringWithFormat and have that string be the title of the alert controller. Here is my countDown method:
@interface ViewController () {
NSString *seconds;
int mainInt;
NSTimer *timer;
}
- (void)countDown{
mainInt = 20;
mainInt -= 1;
seconds = [NSString stringWithFormat:@"%i", mainInt];
if (mainInt == 0) {
[timer invalidate];
}
}
and this is the UIAlertController triggered by an IBAction. When triggered the controller gets viewed modally and the title says "null seconds" wait for a few more seconds and try to trigger the logout button again and you get a title saying "19 seconds".
- (IBAction)logout:(id)sender {
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countDown) userInfo:nil repeats:YES];
NSString *logOutString = [NSString stringWithFormat:@"%@ seconds.", seconds];
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:nil
message:logOutString
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
NSLog(@"Cancel Log out");
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"log Out", @"Ok action") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
NSLog(@"Loged out");
//Log out code goes here
//When time is up, log out automatically
}];
[alertController addAction:okAction];
[alertController addAction:cancelAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];
[self presentViewController:alertController animated:YES completion:nil];
}
回答1:
Your first problem is that you don't initialise seconds
to anything, so it will initially be nil. This is why your alert says "null seconds". On a subsequent display of the alert, seconds will have been set by your countDown
method.
Your second problem is that you aren't actually updating the message
property of your alert, so you just see the value of seconds
when the alert was initially displayed.
Finally, you set mainInt
to 20 and then subtract 1 each time the timer fires, so it will never reach 0, it will be 20,19,20,19,20,19...
The code below initialises mainInt
in the IBAction method so it isn't reset to 20 each time the tier ticks. It also updates the message
property of the alert and dismisses the alert when the timer reaches 0 (it actually does it 1 second after because I think it is nicer to see 2..1...0...logout but you can change that)
@interface ViewController () {
int mainInt;
NSTimer *timer;
UIAlertController *alertController;
}
- (NSString *)countDownString {
return [NSString stringWithFormat:@"%i seconds", mainInt];
}
- (void)countDown{
mainInt -= 1;
if (mainInt < 0) {
[timer invalidate];
[alertController dismissViewControllerAnimated:YES completion:^{
// Whatever you need to do to complete the logout
}]
} else {
alertController.message=[self countDownString];
}
}
- (IBAction)logout:(id)sender {
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countDown) userInfo:nil repeats:YES];
mainInt=20;
alertController = [UIAlertController
alertControllerWithTitle:nil
message:[self countDownString]
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
[timer invalidate];
NSLog(@"Cancel Log out");
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"log Out", @"Ok action") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
[timer invalidate];
NSLog(@"Loged out");
//Log out code goes here
//When time is up, log out automatically
}];
[alertController addAction:okAction];
[alertController addAction:cancelAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];
[self presentViewController:alertController animated:YES completion:nil];
}
来源:https://stackoverflow.com/questions/36048240/countdown-nstimer-in-title-of-a-uialertcontroller-getting-a-null-instead-of-time