0

I m using timer on circular progress bar and taken NSDate property in interface (tested also taking in viewWillAppear) but when viewController loads it show starting from 27 seconds remain, while i have set its value to 30 seconds.

My scenario is, a user has a question and optional answers and he/she has some time suppose 30 seconds when he/she click start button than another screen opens after this screen loads time start should be from 30 seconds.

@interface TestViewController ()

 {
    NSTimeInterval totalCountdownInterval;
    NSDate* startDate;
 }
}

-(void)viewWillAppear:(BOOL)animated{

    [self startTimer];
    totalCountdownInterval = 30.0;
    startDate = [NSDate date];
}

-(void)startTimer {

      if (!_timer) {
          _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                  target:self
                                                selector:@selector(timerFired:)
                                                userInfo:nil
                                               repeats:YES];
    }
}

-(void)stopTimer {

      if ([_timer isValid]) {
          [_timer invalidate];
      }
      _timer = nil;
}

-(void)timerFired:(NSTimer *)timer {

    NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
    NSTimeInterval remainingTime = totalCountdownInterval - elapsedTime;

    CGFloat timeRemain = remainingTime;
    NSLog(@"%f", timeRemain);
    if (remainingTime < 0.0) {
        [_timer invalidate];
    }

    [_circleProgressBar setHintTextGenerationBlock:(^NSString *(CGFloat progress) {

        if (!(timeRemain < 0.9)) {
            progress = timeRemain - 1;
            return [NSString stringWithFormat:@"%.0f", progress];
        }else{
            progress = 0;
            return [NSString stringWithFormat:@"%.0f", progress];
        }

    })];
    [_circleProgressBar setProgress:(_circleProgressBar.progress + 0.0333f) animated:YES];
}

-(void) viewWillDisappear:(BOOL)animated {
    [self stopTimer];
}

Any help will be appreciated. Thanks.

MRizwan33
  • 2,723
  • 6
  • 31
  • 42

2 Answers2

1

use that timer code in void view did appear and try once.

- (void)viewDidAppear:(BOOL)animated
{

[self startTimer];
totalCountdownInterval = 30.0;
startDate = [NSDate date];
}
1

The first timer event will be fired after 1 second is passed, so you should see 29 first. So you should display the number 30 manually somehow, outside the timer event.

And you subtract 1 in your code in setHintTextGenerationBlock : progress = timeRemain - 1; which will make you see 28 as initial.

And as final you should start timer in viewDidAppear instead of viewWillAppear where you lose another second and come to 27.

To correct code should be like:

@interface TestViewController ()

 {
    NSTimeInterval totalCountdownInterval;
    NSDate* startDate;
 }
}

-(void)viewDidLoad {
    [_circleProgressBar setHintTextGenerationBlock:(^NSString *(CGFloat progress) {

        return [NSString stringWithFormat:@"%.0f", progress * 30];

    })];
    [_circleProgressBar setProgress:1.0) animated:NO];
}

-(void)viewDidAppear:(BOOL)animated{

    [self startTimer];
    totalCountdownInterval = 30.0;
    startDate = [NSDate date];
}

-(void)startTimer {

      if (!_timer) {
          _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                  target:self
                                                selector:@selector(timerFired:)
                                                userInfo:nil
                                               repeats:YES];
    }
}

-(void)stopTimer {

      if ([_timer isValid]) {
          [_timer invalidate];
      }
      _timer = nil;
}

-(void)timerFired:(NSTimer *)timer {

    NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
    NSTimeInterval remainingTime = totalCountdownInterval - elapsedTime;

    CGFloat timeRemain = remainingTime;
    NSLog(@"%f", timeRemain);
    if (remainingTime < 0.0) {
        [_timer invalidate];
    }

    [_circleProgressBar setProgress:(1.0 * timeRemain / 30.0) animated:YES];
}

-(void) viewWillDisappear:(BOOL)animated {
    [self stopTimer];
}

You should set progress to 1.0 in the beginning and count down to 0.0 in 30 steps. Set hint generation block to display something meaningful for 1.0 - 0.0 as 30 - 0.

mtkale
  • 1,195
  • 1
  • 8
  • 7
  • yes i think this is the reason. so i need solution Please. i have to show decreasing down timer. – MRizwan33 Mar 20 '18 at 07:31
  • Use viewDidAppear instead of viewWillAppear. Don't subtract 1 in setHintTextGenerationBlock. and set [_circleProgressBar setProgress:30] in viewDidLoad. – mtkale Mar 20 '18 at 11:28
  • not getting you. [_circleProgressBar setProgress:30] don't have this interface in this library. – MRizwan33 Mar 20 '18 at 11:36
  • please update your answer so that i can accept if useful for me. thanks. – MRizwan33 Mar 20 '18 at 11:37
  • yes, you are correct, it should be [_circleProgressBar setProgress:30 animated:false] – mtkale Mar 20 '18 at 11:47
  • not working progressBar showing 0 second left. which is not solving my problem. it should be 30. – MRizwan33 Mar 20 '18 at 11:52
  • You should also move your [_circleProgressBar setHintTextGenerationBlock: ...] block outside the timerFired event, probably to viewDidLoad. You should remove timeRemain in this block and only return [NSString stringWithFormat:@"%.0f", progress * 30]; should stay. – mtkale Mar 20 '18 at 12:26
  • And [_circleProgressBar setProgress:1.0 animated:false] in viewDidAppear and not 30 – mtkale Mar 20 '18 at 12:27
  • please update your answer with code sample i have given above. – MRizwan33 Mar 20 '18 at 12:28
  • progressBar goes very fast within one second it fills up all bar. not getting you. please give me code description. so that i can understand clearly. – MRizwan33 Mar 20 '18 at 12:41
  • There is one more update which sets initial progress. – mtkale Mar 20 '18 at 12:42
  • What is the output now? – mtkale Mar 20 '18 at 12:58
  • how to set initial progress? – MRizwan33 Mar 20 '18 at 13:05
  • It is already in viewDidLoad, [_circleProgressBar setProgress:1.0) animated:NO]; – mtkale Mar 20 '18 at 13:19
  • than not moving progress bar according to seconds which are 30. it move just in one second and completes. – MRizwan33 Mar 20 '18 at 13:21
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167229/discussion-between-mtkale-and-mrizwan33). – mtkale Mar 21 '18 at 06:45