CountDown classで実装したカウントダウンタイマーによって0.01秒ごとに変化する数値を、GameViewControllerのLabelに反映させたいです。(カウントダウンを実装させているファイルと、その数値を表示させたいファイルが別ということです)
ソースコードについてはもう少し下の方で記載しております。
1つのView内でカウントダウンを実装させて、それをLabelに反映させることは可能なのですが、そのViewには他にも色々なことを実装させたいため、別Modelでカウントダウンを実装させようと考えました。
ネットの情報を探し回りましたが、解決することが出来なかったため、ここで質問させて頂きました。
swiftを勉強して初めて作るアプリになります。
発生している問題・エラーメッセージ
GameViewController内の
GameViewController
1timerLabel.text = timerCountString
の部分で下記エラーが発生してプログラムが止まってしまいます。
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
該当のソースコード
GameViewController
1import UIKit 2 3class GameViewController: UIViewController { 4 5 @IBOutlet weak var timerLabel: UILabel! //ここに数値を反映させたい 6 var countDown = CountDown() //カウントダウンを実装しているclass 7 var timerCountString: String = "" //この変数をtimerLabel.textに入れる 8 9 10 override func viewWillAppear(_ animated: Bool) { 11 super.viewWillAppear(animated) 12 13 countDown.startTimer() //別クラスの関数を発動 14 } 15 16 func updateTimerLabel() { // カウントダウンをこのclassに反映させるための関数 17 print(timerCountString) //ここまでは値が渡ってきている 18 timerLabel.text = timerCountString //ここでエラーが発生する 19 }
CountDown
1import Foundation 2 3class CountDown { 4 5 var t = Double() 6 var timer = Timer() 7 var startTime: TimeInterval? = nil 8 var timerCountString: String = "" 9 10 func startTimer() { 11 startTime = Date.timeIntervalSinceReferenceDate 12 timer = Timer.scheduledTimer( 13 timeInterval: 0.01, 14 target: self, 15 selector: #selector(update), 16 userInfo: nil, 17 repeats: true) 18 } 19 // 10.00秒から0.01秒ずつカウントダウンさせたい 20 @objc func update() { 21 if let startTime = startTime { 22 t = 10.00 - (Date.timeIntervalSinceReferenceDate - startTime) 23 } 24 if t <= 0 { // 残り0秒になったらタイマーを止める 25 t = 0 26 timer.invalidate() 27 } 28 timerCountString = String(format: "%.2f", t) //小数点を制限 29 let gameVC = GameViewController() 30 gameVC.timerCountString = timerCountString // 数値を渡す 31 gameVC.updateTimerLabel() // gameVCの関数を発動 32 } 33}
最初は
CountDown
1let gameVC = GameViewController() 2gameVC.timerLabel.text = timerCountString // Labelのtextに直接値を渡す
のように記述していましたが、色々調べたところ、いったんLabelがあるviewに値を渡す方が良さそうだったので、いったん値を渡す内容に書き換えて、それを0.01秒ごとにLabel.textに反映させたいがために、関数を関数で呼ぶような形になりました。がそれは今回の直接的な原因ではありませんでした・・・。
試したこと
その1
CountDownに実装している内容をGameViewControllerに実装すると、きちんとLabel.textに反映します。
しかし、今回は別Modelで実装した内容をGameViewControllerに反映させたいです。
その2
GameViewController
1func updateTimerLabel() { 2 print(timerCountString) 3 timerLabel.text = "test" // ここを変更 4 }
のようにtimerLabel.textに代入する内容を簡略化した場合でも、同様のエラーは発生します。
ですので、代入する値自体が問題ではないと考えております。
その3
GameViewController
1func updateTimerLabel() { 2 print(timerCountString) 3 }
だけの記述にすると、
9.99
9.98
9.97
9.96
9.95
のようにアウトプットされて0.00まで問題なく進むため、ここまで値は渡ってきていることは確かだと思うのですが、これを
GameViewController
1timerLabel.text = timerCountString
のようにLabelのtextに反映させようとするとエラーが発生するため、このLabel.textと関数を使ったファイル間のデータ移動の何かに問題があるのだと思うのですが、未だに原因を掴めておりません。
お手数をおかけしますが、この問題を解決するためのアドバイスを頂ければ幸いです。
よろしくお願い致します。
補足情報(FW/ツールのバージョンなど)
Version 11.3.1 (11C504)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/24 03:16
2020/02/24 12:02