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

发布于 2024-10-07 01:15:10 字数 195 浏览 1 评论 0原文

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

5 4 3 2 1

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

我尝试使用 NSTimer SchedulerWithTimeInterval 对其进行编码,但惨败。

请帮我。

I want to show a countdown timer using a UILabel which will start from 5 and reduces by 1 every second like:

5
4
3
2
1

and finally hides the label when it reaches 0.

I tried to code it using NSTimer scheduledTimerWithTimeInterval but failed miserably.

Please help me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔女人霸气范 2024-10-14 01:15:10

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

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

I was just doing something like that. I have a UILabel that is called timeReamin in my code. It's updated every second until it reaches 0 and then an alert is displayed. I must warn you that since the timer runs on the same thread as your UI, you may experience some jitter. I have not solved that problem yet, but this works for simple timers. Here is code that I am using:

- (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.
}

Figured out a threaded solution that removes the jitter. In the viewDidLoad method or applicationDidFinishLaunching, you need a line such as:

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

This will launch a thread using the createTimer method. However, you also need to update the createTimer method as well:

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

Most of this is standard thread entry routine stuff. The pool is used for managed memory strategies employed by the thread which. This is not needed if you are using garbage collection, but it does not hurt. The runloop is an event loop that is executed continuously to generate the events when the time elapses every second. There is a runloop in your main thread that is created automatically, this is a runloop that is specific to this new thread. Then notice that there is a new statement at the end:

[runLoop run];

This ensures that the thread will execute indefinitely. You can manage the timer, such as restarting it or setting it for different values within the other methods. I initialize my timer at other places in my code and that is why that line has been removed.

花伊自在美 2024-10-14 01:15:10

这是使用 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;
}

Here is an example using scheduledTimerWithTimeInterval. To use:

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.

In your .h:

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

In your .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;
}
尐籹人 2024-10-14 01:15:10

这是倒计时器的最终解决方案。您还可以使用来自 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];

    }



}

This is the final solution for countdown timer. You can also use start and end dates comming from the web service or you can also use current system date.

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

    }



}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文