【发布时间】:2018-02-11 17:47:31
【问题描述】:
我正在制作一个应用程序,用户可以同时设置多个计时器并在列表视图中查看它们。
我知道锻炼时间有两种主要选择:
- 从当前日期减去开始日期(当前日期-开始日期)
或
- 使用 NSTimer 并从每个活动计时器中每秒缩短 1 秒。
我以前一直在使用后者,但是浏览了互联网后,我开始认为数据可能会更好。
请您告诉我您认为最好使用哪个,如果您选择了第一个(日期),请您提供一些有关如何使用它的示例代码。
【问题讨论】:
我正在制作一个应用程序,用户可以同时设置多个计时器并在列表视图中查看它们。
我知道锻炼时间有两种主要选择:
或
我以前一直在使用后者,但是浏览了互联网后,我开始认为数据可能会更好。
请您告诉我您认为最好使用哪个,如果您选择了第一个(日期),请您提供一些有关如何使用它的示例代码。
【问题讨论】:
两个都用。您有一个每秒重复的Timer。 Timer 的处理程序然后遍历每个用户计时器的开始日期列表,并根据当前日期更新每个计时器的显示。
【讨论】:
let seconds = date1.timerIntervalSince(date2)
您可以使用 NSTimer 并从每个活动计时器中每秒减少 1 秒。你可以使用这个类。
class CustomTimer {
typealias Update = (Int)->Void
var timer:Timer?
var count: Int = 0
var update: Update?
init(update:@escaping Update){
self.update = update
}
func start(){
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerUpdate), userInfo: nil, repeats: true)
}
func stop(){
if let timer = timer {
timer.invalidate()
}
}
/**
* This method must be in the public or scope
*/
@objc func timerUpdate() {
count += 1;
if let update = update {
update(count)
}
}
}
要使用多个计时器,您可以创建多个 CustomTimer 实例,示例代码:
let timer1 = CustomTimer { (seconds) in
// do whatever you want
}
timer1.start()
let timer2 = CustomTimer { (seconds) in
// do whatever you want
}
timer2.start()
注意:
timerUpdate 方法会以 1 秒的间隔准确调用。为了给函数执行留出一些空间,我们可以根据执行所用的时间将间隔设置为 0.9 或 0.95。
【讨论】:
如何使用滑块添加第二个计时器倒计时,以从 30 分钟/45 分钟/60 分钟等更改,以及我在当前 ViewController 中已有的计时器倒计时,因为我已经尝试添加了几次另一个,但似乎总是与当前代码发生冲突,或者导致我正在工作的当前计时器同时倒计时。我需要另一个计时器倒计时独立于当前工作计时器运行。 这是我目前的工作。 谢谢。
//
// ViewController.swift
// Shot Clock 5
//
// Created by Marcus Allen on 16/03/2022.
//
import UIKit
import AVFoundation
import SwiftUI
class ViewController: UIViewController, UITextFieldDelegate{
var seconds = 30
var timer = Timer()
var audioPlayer = AVAudioPlayer()
var isPlaying = false
@IBOutlet weak var label: UILabel!
@IBOutlet weak var sliderOutlet: UISlider!
@IBAction func slider(_ sender: UISlider)
{
seconds = Int(sender.value)
label.text = String(seconds)
}
@IBAction func name2(_ sender: UITextField) {
sender.resignFirstResponder()
}
@IBAction func name1(_ sender: UITextField) {
sender.resignFirstResponder()
}
@IBAction func score2(_ sender: UITextField) {
sender.resignFirstResponder() }
@IBAction func score1(_ sender: UITextField) {
sender.resignFirstResponder()
}
@IBOutlet weak var startOutlet: UIButton!
@IBAction func start(_ sender: Any)
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.counter), userInfo: nil, repeats: true)
sliderOutlet.isHidden = true
startOutlet.isHidden = true
}
@objc func counter()
{
seconds -= 1
label.text = String(seconds) + ""
if (seconds == 0)
{
timer.invalidate()
}
if (seconds == 5)
{
do {
}
sliderOutlet.isHidden = false
startOutlet.isHidden = false
audioPlayer.play()
}
}
@IBAction func EXT2(_ sender: UIButton) {seconds += 15 }
@IBAction func ext2pressed(_ sender: UIButton) {
sender.backgroundColor = sender.backgroundColor == UIColor.red ? UIColor.clear : UIColor.red }
@IBAction func EXT1(_ sender: UIButton) {seconds += 15 }
@IBAction func ext1pressed(_ sender: UIButton) {
sender.backgroundColor = sender.backgroundColor == UIColor.red ? UIColor.clear : UIColor.red
}
@IBAction func ext1resetaudio(_ sender: Any) {
audioPlayer.stop()
audioPlayer.currentTime = 0
isPlaying = false }
@IBAction func ext2resetaudio(_ sender: Any) {
audioPlayer.stop()
audioPlayer.currentTime = 0
isPlaying = false }
@IBOutlet weak var stopOutlet: UIButton!
@IBAction func stop(_ sender: Any)
{
timer.invalidate()
seconds = 30
sliderOutlet.setValue(30 , animated: true)
label.text = "30"
audioPlayer.stop()
sliderOutlet.isHidden = false
startOutlet.isHidden = false
}
@IBAction func stopresetaudio(_ sender: Any) {
audioPlayer.stop()
audioPlayer.currentTime = 0
isPlaying = false }
override func viewDidLoad()
{
super.viewDidLoad()
do
{
let audioPath = Bundle.main.path(forResource: "3", ofType: ".mp3")
try audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath!))
}
catch {
//ERROR
}
}
}
【讨论】: