简体   繁体   中英

IOS Stop Countdown Timer at 0

I'm a new programmer (learning objective-c on my own). 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. 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. It's ARC enabled.

Here's the code for the .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:

#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. If I leave the ! in the if statement then when the app opens the alert immediately fires, but the countdown never starts. 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.

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. so [timerLabel isEqual:0] always equals false, which is why negating the entire if statement makes the alert fire. You need to think of an alternative way of counting 10 repetitions of the NSTimer firing.

Try keeping a count of how many times updateCountDown has fired using a static int declared in that method.

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. The original execution continues as normal, checking your condition and then exiting 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 .
  3. One second later, your timer fires, executing updateCountDown .

Your exercisePopup method is never called because you do not check your condition in updateCountDown .

Object Comparison :

Your comparison of timerLabel using isEqual: and the integer literal 0 is the same as if you had written:

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" .

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

However, this is not the best way to compare times. You should consider using NSTimeInterval s and comparing them. 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.

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.

@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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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