【问题标题】:iPhone: How to code a reducing countdown timer?iPhone:如何编写递减倒数计时器?
【发布时间】:2011-05-24 15:08:06
【问题描述】:

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

5 4 3 2 1

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

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

请帮帮我。

【问题讨论】:

  • 向我们展示失败的代码。

标签: ios4 nstimer


【解决方案1】:

我只是在做类似的事情。我的代码中有一个名为 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];

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

【讨论】:

    【解决方案2】:

    这是一个使用 scheduleTimerWithTimeInterval 的示例。使用方法:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多