2016-01-07 2 views
-1

Другие вопросы, которые я видел на этом, не помогли. Я хочу, чтобы можно было начать, приостановить, а затем возобновить NSTimer. Я знаю, как запустить NSTimer. Я также знаю, что вы не можете «приостановить» NSTimer, но вы можете аннулировать его. Но что мне делать, если бы я хотел возобновить его, сохраняя то же время, что и я, когда останавливал таймер? Вот код:Возобновление NSTimer в Swift

var startTimer = NSTimeInterval() 
var timer = NSTimer() 
@IBOutlet var displaylabel: UILabel! 
@IBAction func start(sender: UIButton) { 
     timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "updateTime", userInfo: nil, repeats: true) 
     startTimer = NSDate.timeIntervalSinceReferenceDate() 
} 
@IBAction func stop(sender: UIButton) { 
timer.invalidate() 
} 
@IBAction func resume(sender: UIButton) { 
// Code needed 
} 
func updateTime() { 
    let currentTime = NSDate.timeIntervalSinceReferenceDate() 
    var elapsedTime: NSTimeInterval = currentTime - startTimer 
    let minutes = UInt8(elapsedTime/60.0) 
    elapsedTime -= (NSTimeInterval(minutes) * 60) 
    let seconds = UInt8(elapsedTime) 
    elapsedTime -= NSTimeInterval(seconds) 
    let fraction = UInt8(elapsedTime * 100) 
    let strMinutes = String(format: "%02d", minutes) 
    let strSeconds = String(format: "%02d", seconds) 
    let strFraction = String(format: "%02d", fraction) 
    displaylabel.text = "\(strMinutes):\(strSeconds).\(strFraction)" 
} 

Заранее спасибо. Антон

+0

Зачем не нравится (-1)? –

+0

'NSTimer' не подходит для этого дизайна; это не «секундомер» (просто то, что вызывает вызов функции в указанное позднее время, необязательно повторяющееся). Вам нужно будет выполнить счетчик самостоятельно. Попробуйте найти «CADisplayLink» (ссылка на анимацию ядра). –

+0

@NicolasMiari Спасибо ... Не могли бы вы дать мне код, если это возможно? –

ответ

2

Вы должны использовать CADisplayLink по двум причинам:

  1. Вы обновления экрана так часто, как это возможно, и не тратить дополнительное время автономной работы пытается обновить его чаще, чем это возможно. Все устройства iOS (за исключением iPad Pro в редких случаях) обновляют экран не более 60 раз в секунду. Планирование вашего таймера в течение 0,01 секунды означает, что вы пытаетесь обновить экран не менее 40 раз в секунду чаще, чем необходимо.

  2. Вы можете приостановить и возобновить CADisplayLink.

Обработка пауз требует немного размышлений. То, что вы хотите сделать, это записать время, когда вы приостанавливаете (отдельно от времени начала), а затем, когда вы возобновляете, увеличивайте время начала на время, прошедшее с момента паузы.

class ViewController: UIViewController { 

    private var startTime = NSTimeInterval(0) 
    private var pauseTime = NSTimeInterval(0) 
    private var displayLink: CADisplayLink! 

    @IBOutlet var label: UILabel! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     displayLink = CADisplayLink(target: self, selector: "displayLinkDidFire") 
     displayLink.paused = true 
     displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) 
    } 

    @IBAction func startWasTapped(sender: AnyObject) { 
     startTime = NSDate.timeIntervalSinceReferenceDate() 
     displayLink.paused = false 
    } 

    @IBAction func resumeWasTapped(sender: AnyObject) { 
     startTime += NSDate.timeIntervalSinceReferenceDate() - pauseTime 
     displayLink.paused = false 
    } 

    @IBAction func stopWasTapped(sender: AnyObject) { 
     pauseTime = NSDate.timeIntervalSinceReferenceDate() 
     displayLink.paused = true 
    } 

    func displayLinkDidFire() { 
     let elapsedTime = NSDate.timeIntervalSinceReferenceDate() - startTime 
     label.text = String(format: "%02.0f:%05.2f", floor(elapsedTime/60), elapsedTime) 
    } 

} 
+0

Я только что внедрил ваше решение для обновления моего видеопрограммы 'UISlider'. Однако слайдер большого пальца движется слишком быстро. Как сделать его тиканием один раз в секунду? ... Я использовал «NSTimer», прежде чем я не знаком с «CADisplayLink» – Pangu

+0

Поскольку в моем решении нет слайдера, я не понимаю, в чем проблема. Может быть, вы должны написать новый вопрос. –

+0

@Pangu Использовать displayLink.frameInterval, например. 60 = 1 секунда – Stonetip

Смежные вопросы