尝试在swift中停止计时器对象时发生致命错误

尝试在swift中停止计时器对象时发生致命错误,swift,watchkit,apple-watch,watchos,watchos-5,Swift,Watchkit,Apple Watch,Watchos,Watchos 5,我目前正在为苹果手表制作秒表。手表有两个接口和两个控制器时间控制器和开关控制器。TimerController运行计时器。我正在尝试从开关控制器停止时间对象,因此,我在开关控制器中创建了一个功能,可以停止我的时间控制器中的计时器。问题是我在TimerController中遇到了一个致命错误,我不知道为什么 timerController中的函数timestop()返回错误: “线程1:致命错误:在展开可选值时意外发现nil” 看看这张图片 错误 开关控制器 时间控制器 框架 时间控制器

我目前正在为苹果手表制作秒表。手表有两个接口和两个控制器<代码>时间控制器和
开关控制器
TimerController
运行计时器。我正在尝试从
开关控制器
停止时间对象,因此,我在
开关控制器
中创建了一个功能,可以停止我的
时间控制器
中的计时器。问题是我在
TimerController
中遇到了一个致命错误,我不知道为什么

timerController
中的函数
timestop()
返回错误:

“线程1:致命错误:在展开可选值时意外发现nil”

看看这张图片

错误

开关控制器

时间控制器

框架

时间控制器

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()
    }

}
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()
    }

}
已更新SwipeController

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()
    }

}
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()
    }

}
更新

首先导入通知中心。 在左侧的项目导航器中单击您的项目。一般来说,请转到“链接框架和库”。单击+按钮,搜索通知中心,然后添加框架

删除整个
TimerViewController
并将其与以下内容一起粘贴:

删除整个
SwipeViewController
并将其与以下内容一起粘贴:

首先。将此项添加到您的
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()

别忘了:在下面添加这个
willActivate()


老办法 您不能使尚未计划的计时器无效。 首先添加一个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()
}
计时器完成时。此块被调用

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

请务必包含试图调用
timeStopp()
SwitchController
中的代码,您如何演示
TimerController
?它是通过一个序列完成的吗?
@IBOutlet
将为零,直到您不显示视图为止。您只需初始化
TimerController
,其所有
控件将为零。使用适当的委托,
var timer=TimerController()
不会给您提供对演示视图控制器的引用,其方法显示@Carpsen90?我是否获得引用??我对斯威夫特很陌生。。。