0

現在、私はストップウォッチが必要なゲームを開発しています.1分と言います.ユーザーが再生ボタンをタップするとゲーム画面に入ります.1分のストップウォッチカウントダウンを実行したい01:00,00:59,00: 58など。そのため、ストップウォッチを実装するにはNSTimerが理想的な選択肢であることがわかりました。したがって、ラベルを取得し、NSTimerのインスタンスを作成し、時間間隔を割り当て、タイマーラベルの値を減らし始めました。

-(void)viewDidAppear:(BOOL)animated
{
    self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(viewWillAppear:) userInfo:nil repeats:YES];
    [super viewDidAppear:YES];
}

-(void)viewWillAppear:(BOOL)animated
{
    static int currentTime = 60;
    int newTime = currentTime--;
    int minutesRemaining = newTime / 60; // integer division, truncates fractional part
    int secondsRemaining = newTime % 60; // modulo division

    self.timerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutesRemaining, secondsRemaining];

    if ([self.timerLabel.text isEqualToString:@"00:00"])
    {
        [stopWatchTimer invalidate];
    }
    [super viewWillAppear:YES];
}

ここでの問題は、タイマーが 01:00、00:59、00:58 の実行を開始し、たとえば 53 秒で続行し、別のビューに移動して戻ってきた場合、00:53、00:52 から実行されていることです。オンですが、01:00から実行したいので、viewDidDisappear ieでNSTimerの無効化を実装しました

-(void)viewDidDisappear:(BOOL)animated
{
    if ([stopWatchTimer isValid])
    {
        [stopWatchTimer invalidate];
        self.stopWatchTimer = nil;
    }
    [super viewDidDisappear:YES];
}

それでも同じ問題が存在します!

この問題について多くの調査を行いましたが、有用で機能する答えは見つかりませんでした。

誰かが私を案内してくれませんか、助けていただければ幸いです。

事前に感謝します:)

4

1 に答える 1

1

viewWillAppearタイマーのセレクターを使用しています。viewWillAppearビューが画面に表示されたときに呼び出される viewController のメソッドです。自分で呼び出すべきではありません。代わりに、タイマーをデクリメントする独自のメソッドを作成します。

-(void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
  currentTime = 60; // This could be an instance variable
  self.timerLabel.text = @"01:00";
}


-(void)updateTime {
  int newTime = currentTime--;
  int minutesRemaining = newTime / 60; // integer division, truncates fractional part
  int secondsRemaining = newTime % 60; // modulo division

  self.timerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutesRemaining, secondsRemaining];

  if ([self.timerLabel.text isEqualToString:@"00:00"])
  {
      [self.stopWatchTimer invalidate];
  }
}

-(void)viewDidDisappear:(BOOL)animated
{
 [super viewDidDisappear:animated];
  if ([self.stopWatchTimer isValid])
  {
    [self.stopWatchTimer invalidate];
    self.stopWatchTimer = nil;
  }
}

この手法では、タイマーが毎秒呼び出しを担当しますが、数秒後にタイミングの問題が発生する可能性があります。より正確なタイミングを得るには、カウントダウンを開始した時刻updateTimeを保存し、呼び出しごとに、現在の時刻と保存されている開始時刻を比較する必要があります。

インターフェイスに追加します。

@property (nonatomic) NSTimeInterval startTime;

次に、実装で:

-(void)viewDidAppear:(BOOL)animated
{
    self.startTime = [NSDate timeIntervalSinceReferenceDate];
    self.duration = 60; // How long the countdown should be
    self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                           target:self
                                                         selector:@selector(updateTime)
                                                         userInfo:nil
                                                          repeats:YES];
    self.timerLabel.text = @"01:00"; // Make sure this represents the countdown time
}

-(void)updateTime {

  int newTime = self.duration - (round([NSDate timeIntervalSinceReferenceDate] - self.startTime));
  int minutesRemaining = newTime / 60; // integer division, truncates fractional part
  int secondsRemaining = newTime % 60; // modulo division

  self.timerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutesRemaining, secondsRemaining];

  if (newTime < 1)
  {
    [self.stopWatchTimer invalidate];

    /* Do more stuff here */

  }
}

-(void)viewDidDisappear:(BOOL)animated
{
 [super viewDidDisappear:animated];
  if ([self.stopWatchTimer isValid])
  {
    [self.stopWatchTimer invalidate];
    self.stopWatchTimer = nil;
  }
}

コードに関する追加の (関連のない) コメント:

実装時にパラメーターを super: [super viewDidDisappear:animated]; の呼び出しにviewDidDisappear:渡します。animated実装するときは、スーパーへの呼び出しにパラメーターをviewDidAppear:渡しanimatedます。また、他のことをする前に、メソッドで最初にこれをスーパーに呼び出すようにしてください

于 2013-05-22T11:17:03.930 に答える