Неустранимая ошибка при попытке остановить объект таймера в swift - PullRequest
0 голосов
/ 11 октября 2018

В настоящее время я работаю над секундомером для Apple Watch.Часы имеют два интерфейса и два контроллера.TimerController и SwitchController.TimerController запускает таймер.Я пытаюсь остановить объект времени из SwitchController и поэтому сделал функцию, которая останавливает таймер в моем TimerController, который я могу достичь в SwitchController.Проблема в том, что я получаю фатальную ошибку в TimerController, и я не могу понять, почему?

функция timeStopp() в timerController возвращает ошибку:

«Поток 1: фатальная ошибка: неожиданно обнаружен ноль при развертывании необязательного значения»

См. Это изображение!

Интерфейсы

Ошибки

SwipeController Ошибка смахивания

TimeController ошибка времени 1 ошибка времени 2

FrameWork Я здесь набираю?

TimerController

import WatchKit
import Foundation

class TimerController: WKInterfaceController {
    @IBOutlet weak var timerOutlet: WKInterfaceTimer!

    var myTimer : Timer?
    var duration : TimeInterval = 45.0 //arbitrary number. 45 seconds

    var isPaused = false //flag to determine if it is paused or not
    var elapsedTime : TimeInterval = 0.0 //time that has passed between 
    pause/resume
    var startTime = NSDate()
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        start_timer()   
        timerOutlet.setTextColor(UIColor.red)

        // Configure interface objects here.
    }

    func start_timer() {
        myTimer = Timer.scheduledTimer(timeInterval: duration, target: 
        self,selector: Selector(("timerDone")), userInfo: nil, repeats: 
        false)
        timerOutlet.setDate(NSDate(timeIntervalSinceNow: duration ) as 
        Date)
        timerOutlet.start()
    }
    func timerDone(){
        //timer done counting down
    }
    @IBAction func pauseResumePressed() {
        //timer is paused. so unpause it and resume countdown
        if isPaused{
            isPaused = false
            myTimer = Timer.scheduledTimer(timeInterval: duration - 
            elapsedTime, target: self, selector: 
            Selector(("timerDone")), userInfo: 
            nil, repeats: false)
            timerOutlet.setDate(NSDate(timeIntervalSinceNow: duration - 
            elapsedTime) as Date)
            timerOutlet.start()
            startTime = NSDate()
            //pauseResumeButton.setTitle("Pause")

        }
            //pause the timer
        else{
            isPaused = true

            //get how much time has passed before they paused it
            let paused = NSDate()
            elapsedTime += paused.timeIntervalSince(startTime as Date)

            //stop watchkit timer on the screen
            timerOutlet.stop()

            //stop the ticking of the internal timer
            myTimer!.invalidate()

            //do whatever UI changes you need to
            //pauseResumeButton.setTitle("Resume")
        }
    }

    override func willActivate() {
        // This method is called when watch view controller is about to 
        be visible to user
        super.willActivate()
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no 
        longer visible
        super.didDeactivate()
    }

}

ОБНОВЛЕНО SwipeController

import WatchKit
import Foundation


class SwipeController: WKInterfaceController {

    //@IBOutlet weak var myTimer: WKInterfaceTimer!
    var timer = TimerController()

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)

        // Configure interface objects here.
    }

    override func willActivate() {
        // This method is called when watch view controller is about to 
be visible to user
        super.willActivate()
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no 
longer visible
        super.didDeactivate()
    }

    /stopp call is made here
    @IBAction func PauseButton() {
       timer.pauseResumePressed()
    }

}

1 Ответ

0 голосов
/ 11 октября 2018

Обновление

Сначала Центр уведомлений об импорте.Нажмите на свой проект в Project Navigator на левой стороне.В общем перейдите в «Связанные фреймворки и библиотеки».Нажмите кнопку + и Поиск центра уведомлений, затем добавьте структуру

Screen

Удалитецелое TimerViewController и вставьте его следующим образом: https://gist.github.com/rawandahmad698/a0095e584eaa4df278a23c92e71cca62

Удалите целое SwipeViewController и вставьте его следующим образом: https://gist.github.com/rawandahmad698/9ac0b7a411b7e88ff44068938a0b250a

Сначала.добавьте это в конце своего кода к вашему TimerController:

import NotificationCenter
extension Notification.Name {
     static let stopTimer = Notification.Name("stopTimer")
}

После этого.на вашем SwipeController отредактируйте эту строку:

@IBAction func PauseButton() {
    // Post notification:
    let userInfo = ["foo": 1, "bar": "baz"] as [String: Any] // you could also transfer data

    NotificationCenter.default.post(name: .stopTimer, object: nil, userInfo: userInfo)
}

Наконец.на вашем TimerController добавьте это к willActivate()

NotificationCenter.default.addObserver(self, selector: #selector(stop_timer(notification:)), name: .stopTimer, object: nil)

НЕ ЗАБЫВАЙТЕ: добавьте это ниже willActivate()

func stop_timer(notification:NSNotification) {

    // Timer is paused. so unpause it and resume countdown
    if isPaused {
        isPaused = false
        timerOutlet.start()
        startTime = NSDate()

    } else {
        isPaused = true

        // Stop watchkit timer on the screen
        timerOutlet.stop()

        // Stop the ticking of the internal timer
        myTimer!.invalidate()

        // Do whatever UI changes you need to

    }

}

Старое решение

Выне может сделать недействительным таймер, который еще не был запланирован.Сначала добавьте NSTimer:

import WatchKit
import Foundation

class TimerController: WKInterfaceController {
    @IBOutlet weak var timerOutlet: WKInterfaceTimer!
    var myTimer : NSTimer?
    var duration : NSTimeInterval = 45.0 //arbitrary number. 45 seconds

    // UPDATE
     var isPaused = false //flag to determine if it is paused or not
      var elapsedTime : NSTimeInterval = 0.0 //time that has passed between pause/resume
    var startTime = NSDate()
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)

        timerOutlet.setTextColor(UIColor.red)


        // Configure interface objects here.
}

Приостановите таймер с помощью кнопки:

 @IBAction func pauseResumePressed() {
    //timer is paused. so unpause it and resume countdown
    if isPaused{
        isPaused = false
        myTimer = NSTimer.scheduledTimerWithTimeInterval(duration - elapsedTime, target: self, selector: Selector("timerDone"), userInfo: nil, repeats: false)
        timerOutlet.setDate(NSDate(timeIntervalSinceNow: duration - elapsedTime))
        timerOutlet.start()
        startTime = NSDate()
        pauseResumeButton.setTitle("Pause")


      }
      //pause the timer
      else{
            isPaused = true

            //get how much time has passed before they paused it
            let paused = NSDate()
            elapsedTime += paused.timeIntervalSinceDate(startTime)

            //stop watchkit timer on the screen
            timerOutlet.stop()

            //stop the ticking of the internal timer
            myTimer!.invalidate()

            //do whatever UI changes you need to
            pauseResumeButton.setTitle("Resume")
        }
    }

Запустите таймер:

func start_timer() {
     myTimer = NSTimer.scheduledTimerWithTimeInterval(duration, target: self,selector: Selector("timerDone"), userInfo: nil, repeats: false)
     timerOutlet.setDate(NSDate(timeIntervalSinceNow: duration ))
     timerOutlet.start()
}

Когда timer завершится.Этот блок вызывается

func timerDone(){
       //timer done counting down
}
...