カウントダウンアプリで動作の中断と再開を正しく動作させたい
現在、カウントダウンアプリを作っております。
カウントダウン中にストップボタンを押して動作を止め、もう一度スタートボタンを押したら動作を再開したいのですが、私の書いたコードですと下の画像の様に見た目はストップしているのですが、スタートをボタンを押すとストップしたはずがしていないことになってしまいます。
どの様なコードに修正したら良いでしょうか。
19 : 45 のときにstopボタンを押します。
その10秒後にstartボタンを押すします。
私の望む処理ではありません19 : 44から再スタートして欲しいのですがこのコードはstopした過去をなくしています。
コード↓↓↓
画像を司るコード
import UIKit
func secondsToTimerLabel(_ seconds : Int) -> String {
let min = seconds / 60
let sec = seconds % 60
return String(format: "%02d : %02d", min, sec)
}
class NextViewController: UIViewController {
@IBOutlet weak var countdwonTimer: UILabel!
@IBOutlet weak var executionTimer: UILabel!
@IBOutlet weak var stopButton: UIButton!
@IBOutlet weak var kyannseruButton: UIButton!
@IBOutlet weak var twentyButton: UIButton!
@IBOutlet weak var thirtyButton: UIButton!
@IBOutlet weak var sixtyButton: UIButton!
@IBOutlet weak var ninetyButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
stopButton.layer.cornerRadius = 30.0
kyannseruButton.layer.cornerRadius = 30.0
twentyButton.layer.cornerRadius = 22.5
thirtyButton.layer.cornerRadius = 22.5
sixtyButton.layer.cornerRadius = 22.5
ninetyButton.layer.cornerRadius = 22.5
self.executionTimer.text = secondsToTimerLabel(TimerManager.shared.count)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
TimerManager.shared.onCountDidSet = { count in
self.executionTimer.text = secondsToTimerLabel(Int(count))
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
TimerManager.shared.onCountDidSet = nil
}
@IBAction func stopButtonAction(_ sender: UIButton) {
if TimerManager.shared.isRunning {
if TimerManager.shared.timer?.isValid == true{
TimerManager.shared.stop()
stopButton.setTitle("start", for: .normal)
twentyButton.isUserInteractionEnabled = true
thirtyButton.isUserInteractionEnabled = true
sixtyButton.isUserInteractionEnabled = true
ninetyButton.isUserInteractionEnabled = true
} else {
TimerManager.shared.restartCount()
stopButton.setTitle("stop", for: .normal)
twentyButton.isUserInteractionEnabled = false
thirtyButton.isUserInteractionEnabled = false
sixtyButton.isUserInteractionEnabled = false
ninetyButton.isUserInteractionEnabled = false
}
} else {
TimerManager.shared.startCount()
stopButton.setTitle("stop", for: .normal)
twentyButton.isUserInteractionEnabled = false
thirtyButton.isUserInteractionEnabled = false
sixtyButton.isUserInteractionEnabled = false
ninetyButton.isUserInteractionEnabled = false
}
}
@IBAction func cancelButtonAction(_ sender: UIButton) {
TimerManager.shared.cancel()
twentyButton.isUserInteractionEnabled = true
thirtyButton.isUserInteractionEnabled = true
sixtyButton.isUserInteractionEnabled = true
ninetyButton.isUserInteractionEnabled = true
TimerManager.shared.count = 0
self.executionTimer.text = secondsToTimerLabel(0)
stopButton.setTitle("start", for: .normal)
}
@IBAction func twentyButtonAction(_ sender: UIButton) {
self.executionTimer.text = secondsToTimerLabel(1200)
TimerManager.shared.nowNumber = 20
}
@IBAction func thertyButtonActiojn(_ sender: UIButton) {
self.executionTimer.text = secondsToTimerLabel(1800)
TimerManager.shared.nowNumber = 30
}
@IBAction func sixtyButtonAction(_ sender: UIButton) {
self.executionTimer.text = secondsToTimerLabel(3600)
TimerManager.shared.nowNumber = 60
}
@IBAction func ninetyButtonAction(_ sender: UIButton) {
self.executionTimer.text = secondsToTimerLabel(5400)
TimerManager.shared.nowNumber = 90
}
}
タイマーを司るコード
import UIKit
class TimerManager {
static let shared = TimerManager()
let settingKey = "timer_value"
let settingKeytwenty = "timer_twenty"
let settingKeythirty = "timer_thirty"
let settingKeysixty = "timer_sixty"
let settingKeyninety = "timer_ninety"
var timer : Timer?
var startDate : Date?
var restartDate : Date?
var count = 0 {
didSet {
onCountDidSet?(Double(count))
}
}
var onCountDidSet : ((_ count : Double) -> Void)? = nil
var nowNumber : Int = 0
var restartBool : Bool = false
init () {
let settings = UserDefaults.standard
settings.register(defaults: [settingKey : 216000])
let settings20 = UserDefaults.standard
settings20.register(defaults: [settingKeytwenty : 1200])
let settings30 = UserDefaults.standard
settings30.register(defaults: [settingKeythirty : 1800])
let settings60 = UserDefaults.standard
settings60.register(defaults: [settingKeysixty : 3600])
let settings90 = UserDefaults.standard
settings90.register(defaults: [settingKeyninety : 5400])
}
func restartCount() {
restartDate = Date()
switch nowNumber {
case 20 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in self.twntytimer(timer)
})
case 30 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: {timer in self.thritytimer(timer)})
case 60 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in
self.sixtytimer(timer)})
case 90 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in
self.ninetytimer(timer)})
default :
print("Invalid value \(nowNumber)")
}
}
func startCount() {
startDate = Date()
if timer == nil {
switch nowNumber {
case 20 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in self.twntytimer(timer)
})
case 30 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: {timer in self.thritytimer(timer)})
case 60 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in
self.sixtytimer(timer)})
case 90 :
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in
self.ninetytimer(timer)})
default :
print("Invalid value \(nowNumber)")
}
}
}
func stop() {
timer?.invalidate()
}
func cancel() {
timer?.invalidate()
timer = nil
}
var isRunning : Bool {
return timer != nil
}
func twntytimer(_ timer : Timer) {
let now = Date()
let sitting = UserDefaults.standard
let timeValue = sitting.integer(forKey: settingKeytwenty)
if restartBool != true {
guard let startDate = startDate else {
return
}
let dateDifference = now.timeIntervalSince(startDate)
count = timeValue - Int(dateDifference)
} else {
guard let restartDate = restartDate else {
return
}
let dateDifference = now.timeIntervalSince(restartDate)
count = timeValue - Int(dateDifference)
}
if count <= 0 {
self.timer?.invalidate()
count = 0
self.timer = nil
}
}
func thritytimer (_ timer : Timer) { //途中ですtwntytimer(_:)が成功したら直します
guard let startDate = startDate else {
return
}
let now = Date()
let dateDifference = now.timeIntervalSince(startDate)
let sitting = UserDefaults.standard
let timeValue = sitting.integer(forKey: settingKeythirty)
count = timeValue - Int(dateDifference)
if count <= 0 {
self.timer?.invalidate()
count = 0
self.timer = nil
}
}
func sixtytimer(_ timer : Timer) { //途中ですtwntytimer(_:)が成功したら直します
guard let startDate = startDate else {
return
}
let now = Date()
let dateDifference = now.timeIntervalSince(startDate)
let sitting = UserDefaults.standard
let timeValue = sitting.integer(forKey: settingKeysixty)
count = timeValue - Int(dateDifference)
if count <= 0 {
self.timer?.invalidate()
count = 0
self.timer = nil
}
}
func ninetytimer(_ timer : Timer) { //途中ですtwntytimer(_:)が成功したら直します
guard let startDate = startDate else {
return
}
let now = Date()
let dateDifference = now.timeIntervalSince(startDate)
let sitting = UserDefaults.standard
let timeValue = sitting.integer(forKey: settingKeyninety)
count = timeValue - Int(dateDifference)
if count <= 0 {
self.timer?.invalidate()
count = 0
self.timer = nil
}
}
}
また、このコードのどこがどうダメなのか教えていただけましたら幸いです。
補足↓↓
上記の処理を行いたいがために
NextController
のstopButton部に下記の二つのコードを追加してみたのですがstop時からカウントダウンがうごかなくなってしまいました。なぜでしょうか
@IBAction func stopButtonAction(_ sender: UIButton) {
if TimerManager.shared.isRunning {
if TimerManager.shared.timer?.isValid == true{
TimerManager.shared.stop()
stopButton.setTitle("start", for: .normal)
twentyButton.isUserInteractionEnabled = true
thirtyButton.isUserInteractionEnabled = true
sixtyButton.isUserInteractionEnabled = true
ninetyButton.isUserInteractionEnabled = true
} else {
TimerManager.shared.restartCount()
TimerManager.shared.startDate = nil //ここです!
TimerManager.shared.restartDate = nil //ここです!
stopButton.setTitle("stop", for: .normal)
twentyButton.isUserInteractionEnabled = false
thirtyButton.isUserInteractionEnabled = false
sixtyButton.isUserInteractionEnabled = false
ninetyButton.isUserInteractionEnabled = false
}
} else {
TimerManager.shared.startCount()
stopButton.setTitle("stop", for: .normal)
twentyButton.isUserInteractionEnabled = false
thirtyButton.isUserInteractionEnabled = false
sixtyButton.isUserInteractionEnabled = false
ninetyButton.isUserInteractionEnabled = false
}
}