简体   繁体   English

iOS停止倒数计时器为0

[英]IOS Stop Countdown Timer at 0

I'm a new programmer (learning objective-c on my own). 我是一名新程序员(自己学习Objective-C)。 I'm trying to make an iPad app that will use a countdown timer as the main view and then use an alert to segue into different views depending on different data I pull from a database. 我正在尝试制作一个iPad应用程序,该应用程序将使用倒数计时器作为主视图,然后使用警报根据我从数据库中提取的不同数据选择不同的视图。 I have been working on it for a couple days and I cannot make this timer stop at 0 and fire the alert that will allow the user to segue into the next view. 我已经进行了几天的工作,无法使此计时器停止在0并触发警报,该警报将允许用户选择进入下一个视图。 It's ARC enabled. 启用了ARC。

Here's the code for the .h: 这是.h的代码:

    #import <UIKit/UIKit.h>

@interface ViewController : UIViewController{
    int eventTime;
    NSDate *eventDate;


    IBOutlet UILabel *timerLabel;

    NSTimer *timer;


}
-(void)updateCountDown;
-(void)exercisePopup;



@end

And for the .m: 对于.m:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateCountDown) userInfo:nil repeats:YES];
    if(![timerLabel isEqual: 0]) {
        [timer invalidate];
        [self exercisePopup];
    }


}


- (void)updateCountDown {

    eventTime = 10;
    eventDate = [NSDate dateWithTimeIntervalSinceNow:eventTime];

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    int units = NSCalendarUnitHour | NSCalendarUnitMinute| NSCalendarUnitSecond;

    NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate: eventDate options:0];

    [timerLabel setText:[NSString stringWithFormat:@"%ld%c:%ld%c:%ld%c", (long)[components hour], 'h', (long)[components minute], 'm', (long)[components second], 's']];


}

-(void)exercisePopup{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Time to Exercise" message:@"It's Time to Exercise, Touch the Screen" delegate:self cancelButtonTitle:@"Touch to Exercise" otherButtonTitles:nil];
    // optional - add more buttons:
    [alert show];
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

The issue I'm having is getting this timer to stop at 0 so that the alert will fire. 我遇到的问题是使计时器停止在0位置,以便触发警报。 If I leave the ! 如果我离开了! in the if statement then when the app opens the alert immediately fires, but the countdown never starts. 在if语句中,然后在应用程序打开时立即触发警报,但倒计时永远不会开始。 If I take it out the countdown goes on forever into negative numbers and such. 如果我将其取出,则倒计时将一直持续到负数等。 I'm not sure what to have the if statement check for since it seems to think the timerLabel is starting at 0. I've also tried moving the if statement around, even making it it's own method and then trying to call that after the timer loads but nothing I've tried is working. 我不确定应该对if语句进行检查,因为似乎认为timerLabel从0开始。我也尝试过移动if语句,甚至使其成为自己的方法,然后尝试在计时器加载,但我尝试过的任何方法都无法正常工作。

I'm totally lost, I've been trying all of the solutions I could find on here for the last couple days and none of them work for what I'm trying to do, I've gotten all kinds of errors when I've implemented them. 我完全迷失了,过去几天来我一直在尝试在这里可以找到的所有解决方案,但是这些解决方案都无法满足我的工作要求,当我遇到问题时,我会遇到各种错误实施了它们。 If anyone has any advice I'd really appreciate it. 如果有人有任何建议,我将不胜感激。

if(![timerLabel isEqual: 0]

This line is your problem. 这行是你的问题。 You're comparing a UILabel with 0, which is the same as checking if this UILabel is nil, which it is not in viewDidLoad because you're loading from a nib file where this label exists. 您正在将UILabel与0进行比较,这与检查此UILabel是否为nil(它不在viewDidLoad因为要从存在此标签的nib文件中进行加载。 so [timerLabel isEqual:0] always equals false, which is why negating the entire if statement makes the alert fire. 因此[timerLabel isEqual:0]始终等于false,这就是为什么否定整个if语句会使警报触发的原因。 You need to think of an alternative way of counting 10 repetitions of the NSTimer firing. 您需要考虑一种计数NSTimer触发的10次重复的替代方法。

Try keeping a count of how many times updateCountDown has fired using a static int declared in that method. 尝试使用该方法中声明的static int来计数updateCountDown触发的次数。

It seems that you are misunderstanding a few things here. 您似乎在这里误解了几件事。

Program Flow : 程序流程

When you instantiate your timer, it goes off on its own and then calls your selector every 1.0 seconds. 实例化计时器时,计时器会自动关闭,然后每1.0秒调用一次选择器。 The original execution continues as normal, checking your condition and then exiting viewDidLoad . 原始执行将照常继续,检查您的条件,然后退出viewDidLoad You never check the condition again. 您再也不会检查条件。 Here's a basic ordering of your events: 这是您的事件的基本顺序:

  1. You create a timer. 您创建一个计时器。
  2. You check to see if timerLabel is not 0 . 您检查是否timerLabel不为0
  3. One second later, your timer fires, executing updateCountDown . 一秒钟后,您的计时器启动,执行updateCountDown

Your exercisePopup method is never called because you do not check your condition in updateCountDown . 永远不会调用您的exercisePopup方法,因为您不检查updateCountDown的条件。

Object Comparison : 对象比较

Your comparison of timerLabel using isEqual: and the integer literal 0 is the same as if you had written: 使用isEqual:timerLabel进行比较,整数文字0就像您写的一样:

if (![timerLabel isEqual:nil]) {

This is clearly not what you intended; 这显然不是您想要的; you are trying to compare the string value associated with the timerLabel to the string value of @"0" . 您正在尝试将与timerLabel关联的字符串值与@"0"的字符串值进行比较。

if (![timerLabel.text isEqualToString:@"0"]) {

However, this is not the best way to compare times. 但是,这不是比较时间的最佳方法。 You should consider using NSTimeInterval s and comparing them. 您应该考虑使用NSTimeInterval并进行比较。 You may also want to look into scheduling your time updates with your display using CADisplayLink so that you're not waiting on a timer that is potentially out-of-sync. 您可能还需要考虑使用CADisplayLink在显示器上安排时间更新,以便您不必等待可能不同步的计时器。

I put this code in a sample project and it works. 我将此代码放在一个示例项目中,并且可以正常工作。 Give it a go. 搏一搏。 I made a few slight changes to what you were trying to do. 我对您要执行的操作做了一些细微更改。 You are doing a couple things incorrectly. 您做错了几件事。 Your if statement that checks if timer is 0 gets called during the viewDidLoadMethod which is immediately called after you start your timer. 将在启动计时器后立即调用的viewDidLoadMethod期间调用检查计时器是否为0的if语句。

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *timerLabel;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic) NSInteger currentTime;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.currentTime = 10;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
}

- (void)updateTimer
{
    NSDate *eventDate = [NSDate dateWithTimeIntervalSinceNow:self.currentTime];

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    int units = NSCalendarUnitHour | NSCalendarUnitMinute| NSCalendarUnitSecond;

    NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate: eventDate options:0];

    [self.timerLabel setText:[NSString stringWithFormat:@"%ld%c:%ld%c:%ld%c", (long)[components hour], 'h', (long)[components minute], 'm', (long)[components second], 's']];
    self.currentTime--;
    if (self.currentTime == 0)
    {
        [self.timer invalidate];
        [self exercisePopup];
    }

}
-(void)exercisePopup{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Time to Exercise" message:@"It's Time to Exercise, Touch the Screen" delegate:self cancelButtonTitle:@"Touch to Exercise" otherButtonTitles:nil];
    // optional - add more buttons:
    [alert show];
}


@end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM