iPhone:如何编码减少倒数计时器?

时间:2010-12-13 11:47:42

标签: ios4 nstimer

我想使用UILabel来显示倒数计时器,该计时器将从5开始,每秒减少1 ,如:

5 4 3 2 1

最后在标签达到0时隐藏标签。

我尝试使用NSTimer scheduledTimerWithTimeInterval对其进行编码,但却失败了。

请帮帮我。

3 个答案:

答案 0 :(得分:8)

我只是在做那样的事情。我的代码中有一个名为timeReamin的UILabel。它每秒更新一次,直到达到0,然后显示警报。我必须警告你,由于计时器与你的UI在同一个线程上运行,你可能会遇到一些抖动。我还没有解决这个问题,但这适用于简单的计时器。这是我正在使用的代码:

- (void)createTimer {       
    // start timer
    gameTimer = [[NSTimer timerWithTimeInterval:1.00 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES] retain];
    [[NSRunLoop currentRunLoop] addTimer:gameTimer forMode:NSDefaultRunLoopMode];
    timeCount = 5; // instance variable
}

- (void)timerFired:(NSTimer *)timer {
    // update label
    if(timeCount == 0){
        [self timerExpired];
    } else {
        timeCount--;
        if(timeCount == 0) {
            // display correct dialog with button
        [timer invalidate];
        [self timerExpired];
         }
    }
    timeRemain.text = [NSString stringWithFormat:@"%d:%02d",timeCount/60, timeCount % 60];
}


- (void) timerExpired {
   // display an alert or something when the timer expires.
}

找出一个消除抖动的线程解决方案。在viewDidLoad方法或applicationDidFinishLaunching中,您需要一行如下:

[NSThread detachNewThreadSelector:@selector(createTimer) toTarget:self withObject:nil];

这将使用createTimer方法启动一个线程。但是,您还需要更新createTimer方法:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
// start timer
gameTimer = [[NSTimer timerWithTimeInterval:1.00 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES] retain];
[[NSRunLoop currentRunLoop] addTimer:gameTimer forMode:NSDefaultRunLoopMode];
[runLoop run];
[pool release];

大多数是标准的线程入口例程。该池用于线程使用的托管内存策略。如果您使用垃圾收集,则不需要这样做,但它不会受到伤害。 runloop是一个事件循环,连续执行以在每秒经过一段时间后生成事件。主线程中有一个自动创建的runloop,这是一个特定于此新线程的runloop。然后注意最后有一个新的声明:

[runLoop run];

这可确保线程无限期执行。您可以管理计时器,例如重新启动计时器或将其设置为其他方法中的不同值。我在我的代码中的其他位置初始化我的计时器,这就是为什么该行已被删除。

答案 1 :(得分:3)

以下是使用scheduledTimerWithTimeInterval的示例。使用:

1. copy the code into your controller
2. Use IB, create on the fly, to wire up a UILabel to countDownLabel and set hidden true
3. call [self startCountDown] when you want the countdown to start (This one counts down from 3 to 0)
4. in the updateTime method fill in the "do whatever part..." when the timer is done.

在你的.h:

int countDown;
NSTimer *countDownTimer;
IBOutlet UILabel *countDownLabel;
@property (nonatomic, retain) NSTimer *countDownTimer;
@property(nonatomic,retain) IBOutlet UILabel *countDownLabel;

在你的.m

@synthesize countDownTimer, countDownLabel;

- (void) startCountDown {
    countDown = 3;
    countDownLabel.text = [NSString stringWithFormat:@"%d", countDown];
    countDownLabel.hidden = FALSE;
    if (!countDownTimer) {
        self.countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1.00 
                                                               target:self 
                                                             selector:@selector(updateTime:) 
                                                             userInfo:nil 
                                                              repeats:YES];
    }
}

- (void)updateTime:(NSTimer *)timerParam {
    countDown--;
    if(countDown == 0) {
        [self clearCountDownTimer];
        //do whatever you want after the countdown
    }
    countDownLabel.text = [NSString stringWithFormat:@"%d", countDown];
}
-(void) clearCountDownTimer {
    [countDownTimer invalidate];
    countDownTimer = nil;
    countDownLabel.hidden = TRUE;
}

答案 2 :(得分:1)

这是倒数计时器的最终解决方案。您还可以使用来自Web服务的开始日期和结束日期,也可以使用当前系统日期。

-(void)viewDidLoad   
{

 self.timer = [NSTimer scheduledTimerWithTimeInterval:(1.0) target:self selector:@selector(updateLabel) userInfo:nil repeats:YES];
 [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

  NSDateFormatter *dateformatter = [[NSDateFormatter alloc] init];
  [dateformatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

 //Date must be assign in date fromat which you describe above in dateformatter
  NSString *strDate = @"PUT_YOUR_START_HERE"; 
  tmpDate = [dateformatter dateFromString:strDate];

   //Date must be assign in date fromat which you describe above in dateformatter  
   NSString *fathersDay = @"PUT_YOUR_END_HERE";
   currentDate = [dateformatter dateFromString:fathersDay];

    timeInterval = [currentDate timeIntervalSinceDate:tmpDate];

}


-(void)updateLabel
{

    if (timeInterval > 0)
    {

        timeInterval--;


        NSLog(@"TimeInterval = %f",timeInterval);


        div_t h = div(timeInterval, 3600);
        int hours = h.quot;
        // Divide the remainder by 60; the quotient is minutes, the remainder
        // is seconds.
        div_t m = div(h.rem, 60);
        int minutes = m.quot;
        int seconds = m.rem;

        // If you want to get the individual digits of the units, use div again
        // with a divisor of 10.

        NSLog(@"%d:%d:%d", hours, minutes, seconds);


       strHrs = ([[NSString stringWithFormat:@"%d",hours] length] > 1)?[NSString stringWithFormat:@"%d",hours]:[NSString stringWithFormat:@"0%d",hours];
       strMin = ([[NSString stringWithFormat:@"%d",minutes] length] > 1)?[NSString stringWithFormat:@"%d",minutes]:[NSString stringWithFormat:@"0%d",minutes];
       strSec = ([[NSString stringWithFormat:@"%d",seconds] length] > 1)?[NSString stringWithFormat:@"%d",seconds]:[NSString stringWithFormat:@"0%d",seconds];



        [lblhh setText:[NSString stringWithFormat:@"%@", strHrs]];
        [lblmm setText:[NSString stringWithFormat:@"%@", strMin]];
        [lblss setText:[NSString stringWithFormat:@"%@", strSec]];

    }
    else
    {

        NSLog(@"Stop");
        [lblhh setText:[NSString stringWithFormat:@"%@", @"00"]];
        [lblmm setText:[NSString stringWithFormat:@"%@", @"00"]];
        [lblss setText:[NSString stringWithFormat:@"%@", @"00"]];

        [self.timer invalidate];

    }



}