Я собрал таймер обратного отсчета, чтобы пользователь мог записывать свои тренировочные сезоны. У меня это работает нормально, за исключением одной части. Пользователь может приостановить сеанс. Пока проблема с кодом заключается в том, что код таймера останавливается, но время продолжает работать.
Например, если пользователь устанавливает таймер на 5 минут и нажимает кнопку запуска, то на полпути пользователь нажимает паузы и ждет 2 минуты (что означает, что истекшее время теперь составляет 7 минут). когда таймер заканчивается 7 минут вместо 5 минут. Если пользователь отменяет сеанс, это нормально, но только потому, что я устанавливаю жесткое время начала и окончания.
Мой вопрос состоит в том, как мне записать время тренировки, если пользователь приостановил таймер?
Вот объяснение пользовательского интерфейса: timerLabel содержит время работы. MinLabel показывает количество минут, в течение которыхПользователь установил таймер на «ClockLabel» показывает количество часов, которые пользователь установил на таймер. Есть два ползунка. Один для установки минут и один для установки часов Есть также две кнопки. A Кнопка Play / Cancel и кнопка Pause / Resume
Заранее спасибо!
import UIKit
import AVFoundation
class Practice_Timmer_VC: UIViewController
{
@IBOutlet weak var navBar: UINavigationItem!
@IBOutlet weak var viewLabel: DesignableLabel!
@IBOutlet weak var timerLabel: DesignableLabel!
@IBOutlet weak var theTabbar: UITabBar!
@IBOutlet weak var minutesLabel: UILabel!
@IBOutlet weak var hoursLabel: UILabel!
var seconds: Int = 60
var timer = Timer()
var isTimerRunning: Bool = false
var resumeTapped: Bool = false
var theTime: String = ""
var startTime: Date = Date()
var endTime: Date = Date()
var total: Int = 0
var chimeSoundEffect: AVAudioPlayer?
override func viewDidLoad()
{
super.viewDidLoad()
theTabbar.selectedItem = theTabbar.items![4]
view.backgroundColor = UIColor(patternImage: UIImage(named: "Carbon.png")!)
startButton.isEnabled = true
pauseButton.isEnabled = false
populateTheTimer()
}// End of viewDidLoad
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
startButton.setImage(UIImage(named: "Play"), for: .normal)
}
func populateTheTimer()
{
let theName = ModelData.getTheTrickName()
navBar.title = theName
}
func getTheDifference(start: Date, end: Date)
{
let theFormatter = DateComponentsFormatter()
theFormatter.allowedUnits = [.hour, .minute]
theFormatter.unitsStyle = .full
theTime = theFormatter.string(from: start, to: end) ?? ""
}
func formattedDate() -> String
{
let formatter = DateFormatter()
let date = Date()
formatter.locale = Locale.current
formatter.dateStyle = .medium
return formatter.string(from: date)
}
func timeString(time: TimeInterval) -> String
{
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i:%02i", hours, minutes, seconds)
}
func runTimer()
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(self.updateTimer)), userInfo: nil, repeats: true)
isTimerRunning = true
pauseButton.isEnabled = true
}
@objc func updateTimer()
{
if seconds < 1
{
timer.invalidate()
endTime = Date()
getTheDifference(start: startTime, end: endTime)
startButton.setImage(UIImage(named: "Play"), for: .normal)
startButton.isEnabled = true
pauseButton.isEnabled = false
playTheSound()
showAlert()
} else {
seconds -= 1
timerLabel.text = timeString(time: TimeInterval(seconds))
}
}
func showAlert()
{
let theAlert = UIAlertController(title: "Practice Ended", message: "\(formattedDate())\nPracticed for: \(theTime)", preferredStyle: .alert)
let saveTheInfo = UIAlertAction(title: "Save Practice", style: .default) { (saveAction) in
self.gotoAddEdit()
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (cancelAction) in
}
theAlert.addAction(saveTheInfo)
theAlert.addAction(cancel)
present(theAlert, animated: true)
}
func playTheSound()
{
let path = Bundle.main.path(forResource: "chime.mp3", ofType: nil)!
let theURL = URL(fileURLWithPath: path)
do {
chimeSoundEffect = try AVAudioPlayer(contentsOf: theURL)
chimeSoundEffect?.play()
} catch {
}
}
func gotoAddEdit()
{
let sb = UIStoryboard(name: "Main", bundle: nil)
if let addEdit = sb.instantiateViewController(withIdentifier: "Practice_Log_VC") as? Practice_Log_VC
{
addEdit.passData = "\(formattedDate())\nPracticed for: \(theTime)"
addEdit.delegate = self as? Timer2PracticeLog_Delegate
self.navigationController?.pushViewController(addEdit, animated: ModelData.isAnimation())
self.navigationController?.view.semanticContentAttribute = .forceLeftToRight
}
}
@IBOutlet weak var startButton: DesignableButton!
@IBAction func startButtonTapped(_ sender: DesignableButton)
{
let minutes2Seconds = Int(minutesSliderOutlet.value) * 60
let hours2Seconds = Int(hoursSliderOutlet.value) * 3600
seconds = Int(minutes2Seconds + hours2Seconds)
if isTimerRunning == false // Start
{
if seconds > 0
{
startTime = Date()
sender.setImage(UIImage(named: "Cancel_Video"), for: .normal)
runTimer()
} else {
view.sendConfirmationAlert(theTitle: "Error! Practice time is set to 0.", theMessage: "Please set the practice time.", buttonTitle: "OK")
minutesSliderOutlet.value = 1
minutesLabel.text = "1 Minute"
}
} else { // Cancel
endTime = Date()
timer.invalidate()
seconds = 0
getTheDifference(start: startTime, end: endTime)
sender.setImage(UIImage(named: "Play"), for: .normal)
minutesSliderOutlet.value = 1
minutesLabel.text = "1 Minute"
hoursSliderOutlet.value = 0
hoursLabel.text = "0 Hours"
timerLabel.text = timeString(time: TimeInterval(seconds))
isTimerRunning = false
pauseButton.isEnabled = false
showAlert()
}
}
@IBOutlet weak var pauseButton: DesignableButton!
@IBAction func pauseButtonTapped(_ sender: DesignableButton)
{
if resumeTapped == false
{
timer.invalidate()
resumeTapped = true
sender.setImage(UIImage(named: "Resume"), for: .normal)
} else {
runTimer()
resumeTapped = false
sender.setImage(UIImage(named: "Pause"), for: .normal)
}
}
@IBOutlet weak var minutesSliderOutlet: UISlider!
@IBAction func minuteSlider(_ sender: UISlider)
{
let minutes = Int(sender.value)
if minutes > 1
{
minutesLabel.text = String(minutes) + " Minutes"
} else {
minutesLabel.text = String(minutes) + " Minute"
}
}
@IBOutlet weak var hoursSliderOutlet: UISlider!
@IBAction func hoursSlider(_ sender: UISlider)
{
let hours = Int(sender.value)
if hours > 1
{
hoursLabel.text = String(hours) + " Hours"
} else {
hoursLabel.text = String(hours) + " Hour"
}
}
}// End of Class