【问题标题】:Countdown NSTimer in title of a UIAlertController getting a null instead of time in secondsUIAlertController 标题中的倒计时 NSTimer 获得 null 而不是以秒为单位的时间
【发布时间】:2016-03-16 22:33:00
【问题描述】:

我正在尝试在 UIAlertController 的标题中显示倒计时。我想要类似“您的会话将在 X 秒内到期”之类的内容。我的想法是创建一个 NSTimer 并将时间存储在 NSString stringWithFormat 中,并将该字符串作为警报控制器的标题。 这是我的倒计时方法:

@interface ViewController () {
    NSString *seconds;
    int mainInt;
    NSTimer *timer;
 }

- (void)countDown{

mainInt = 20;
mainInt -= 1;

seconds = [NSString stringWithFormat:@"%i", mainInt];

if (mainInt == 0) {
    [timer invalidate];
   }

}

这是由 IBAction 触发的 UIAlertController。触发时,控制器会以模态方式查看,并且标题显示“null seconds”,再等待几秒钟,然后尝试再次触发注销按钮,您会看到标题显示“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];

}  

【问题讨论】:

    标签: ios objective-c cocoa-touch


    【解决方案1】:

    您的第一个问题是您没有将 seconds 初始化为任何内容,因此它最初将为 nil。这就是您的警报显示“空秒”的原因。在随后显示警报时,您的 countDown 方法将设置秒数。

    您的第二个问题是您实际上并未更新警报的 message 属性,因此您只会在警报最初显示时看到 seconds 的值。

    最后,您将mainInt 设置为 20,然后每次定时器触发时减 1,所以它永远不会达到 0,它将是 20,19,20,19,20,19...

    下面的代码在 IBAction 方法中初始化 mainInt,因此它不会在每次层级滴答时重置为 20。它还会更新警报的message 属性,并在计时器达到 0 时关闭警报(实际上它会在 1 秒后执行,因为我认为看到 2..1...0...logout 会更好,但你可以改变)

    @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];
    
    } 
    

    【讨论】:

    • 有趣。您可以更改 UIAlertController 的消息属性并自动更新?凉爽的。 (已投票。)标题呢?
    • 只是 if 循环中的一个小修正 [self.alert...] 应该只是 [alertController ...] 谢谢@paulw11。我认为您不能自动更新标题...至少使用这种方法
    • @DuncanC 是的,您还可以更改title 属性,它将反映在警报中
    • 很高兴知道。那可能很有用。您可以更改警报中的一组操作(以及按钮)吗? (诚​​然,这将是一个可怕的用户体验 - 我只是好奇。)
    • @duncanc 是的,您可以根据需要添加任意数量的按钮和操作,但要以用户体验为代价。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多