2017-11-03 8 views
0

をクリックします。NSTimerとUIAlertControllerボタン私は単純なコード以下のいる

- (void)showAlert { 
    countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f 
                 target:self 
                selector:@selector(countdown) 
                userInfo:nil 
                repeats:YES]; 

    [UIAlertController showAlertViewWithTitle:@"Title" message:@"" cancelButtonTitle:@"Dismiss" okButtonTitle:nil cancelAction:nil okAction:nil]; 
} 

- (void)countdown { 
    if(secondsLeft > 0) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      _timerLabel.text = [NSString stringWithFormat:@"%ds", secondsLeft]; 
     }); 
     secondsLeft--; 
    } else { 
     [self showTimerLabel:NO]; 
     [countdownTimer invalidate]; 
    } 
} 

ので、タイマーが警告表示とともに始まりますが、私は、アラートのボタンを押すと、timerLabelテキストの更新と遅延が発生しますが。

たとえば、7秒でボタンを押すと、timerLabelは5秒または4秒にジャンプします。

何が間違っている可能性がありますか?

+1

timerメソッドには 'dispatch_async'は必要ありません。タイマーはすでにメインキューで実行されています。 'NSTimer'は特に正確ではありません。単純なカウンタを減らすのではなく、開始時に 'Date'をとり、' timeIntervalSinceNow'を使って経過時間を取得します。スムーズな更新を確実にするために、1秒ではなく0.1秒でタイマーを実行してください。 – Paulw11

答えて

0

CADisplayLinkを使用してこれを行うことができます。 https://www.hackingwithswift.com/example-code/system/how-to-synchronize-code-to-drawing-using-cadisplaylink

以下は、必要に応じてswift 3.0のコードです。私は後で目的Cのコードを準備します。これがあなたにアイデアを与えることを願っています。

var secondsLeft = 10 
var startTime: Date! 
var cumulative: TimeInterval = 0.0 

func timeUpdate(displayLink: CADisplayLink) { 
    guard secondsLeft == 0 else { 
     let current = Date() 
     let seconds = current.timeIntervalSince(startTime) 
     cumulative = cumulative + seconds 
     let elapsed = Int(cumulative) 
     if elapsed >= 1 { 
      secondsLeft = max(0, secondsLeft - elapsed) 
      if secondsLeft == 0 { 
       displayLink.invalidate() 
      } 
      cumulative = cumulative - Double(elapsed) 
     } 
     startTime = current 
     tickLabel.text = String(secondsLeft) 
     return 
    } 
    displayLink.invalidate() 
} 

func showAlert() { 
    startTime = Date() 
    let displayLink = CADisplayLink(target: self, selector: #selector(timeUpdate)) 
    displayLink.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode) 

    let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert) 

    let destroyAction = UIAlertAction(title: "OK", style: .destructive) { action in 

    } 
    alertController.addAction(destroyAction) 

    present(alertController, animated: true, completion: nil) 
} 
関連する問題