タイマーが1秒ごとに動かない(一度に2回呼ばれてしまう)
画面遷移先(ここではEditPopUpViewController)でユーザーが時間を設定し、遷移元のタイマーにそれを反映させ、タイマーを機能させようとしています。
具体的な流れは、
①editTask
ボタン(identifier: "goEditPopUp"
)を押して、画面遷移
②遷移先にあるwheelTimerOutlet
(UIDatePicker
のcountDownTimer
)を使って時間を設定し、doneOutlet
ボタンを押して遷移元に戻る
③その設定された時間を遷移元に反映させて、タイマースタート。taskContent
ラベルに残り時間を毎秒表示
(④stop
ボタンでタイマー停止)
です。
しかし、これをランすると、taskContent
ラベルにあるタイマーの残り時間が2秒ずつ減ってしまいます。そして、stop
ボタンを押すと1秒ごとに減るようになります。原因は最初の段階でタイマーが二度呼ばれてしまっていることにあるようです。
どうしたら解決できるでしょうか。
以下コードです。簡単のため本件に関係ないと判断した機能は省略させていだだきました。分かりにくいところがあればコメントにてお知らせ下さい。なるべくすぐに対応します。
import UIKit
class FirstViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
stop.addTarget(self, action: #selector(stopTimer), for: .touchUpInside)
//・・・
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//・・・
@IBOutlet weak var taskContent: UILabel!
@IBOutlet weak var editTask: UIButton!
@IBOutlet weak var stop: UIButton!
var count = Date(timeIntervalSinceReferenceDate: 0.0)
var timer = Timer()
//画面遷移から戻ってくる時
@IBAction func unwindToFirstView(segue: UIStoryboardSegue)
{
if segue.identifier == "backToFVCdone"
{
//遷移先の取得に失敗したら何もしない
guard let EditPopUpVC = segue.source as? EditPopUpViewController else
{
return
}
//EditPopUpVCのプロパティcountAtEditをcountに受け渡す
count = Date(timeIntervalSinceReferenceDate: EditPopUpVC.wheelTimerOutlet.countDownDuration)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH時間mm分ss秒"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
taskContent.text = dateFormatter.string(from: count)
//タイマー開始
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(FirstViewController.countDown), userInfo: nil, repeats: true)
}
}
func countDown()//この関数が二回呼ばれている
{
count -= 1
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH時間mm分ss秒"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
taskContent.text = dateFormatter.string(from: count)
//カウントダウンが終了したらタイマーを止める
if count.timeIntervalSinceReferenceDate <= 0.0
{
timer.invalidate()
taskContent.text = "終了!"
}
}
func stopTimer()
{
timer.invalidate()
}
//画面遷移のとき
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "backToFVCdone"
{
//略
//実際はもう数種類のUILabel等があり、ここではそのラベルを表示させる・させないを切り替えています
}
else if segue.identifier == "goEditPopUp"
{
//・・・
let EditPopUpVC = segue.destination as! EditPopUpViewController
EditPopUpVC.taskContentAtEditVC = taskContent
//・・・
}
}
}
//画面遷移先のViewController
class EditPopUpViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var taskContentAtEditVC: UILabel!
@IBOutlet weak var wheelTimerOutlet: UIDatePicker!
@IBOutlet weak var doneOutlet: UIButton!
@IBAction func doneActive(_ sender: Any)
{
performSegue(withIdentifier: "backToFVCdone", sender: self)
dismiss(animated: true, completion: nil)
}
}