Ios 快速创建独立计时器
我正在尝试制作一个连接到按钮的倒计时计时器,目前正在使用Ios 快速创建独立计时器,ios,swift,swift4,nstimer,Ios,Swift,Swift4,Nstimer,我正在尝试制作一个连接到按钮的倒计时计时器,目前正在使用 timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true) 然而,我想要它,所以如果我按下相同的按钮,一个新的计时器将以类似的设置启动,因此在控制台中有2个、3个等。同时运行倒计时计时器。 如何使每当我按下按钮时,新计时器生成的设置与
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
然而,我想要它,所以如果我按下相同的按钮,一个新的计时器将以类似的设置启动,因此在控制台中有2个、3个等。同时运行倒计时计时器。
如何使每当我按下按钮时,新计时器生成的设置与前一个相同,但旧计时器仍处于活动状态并在滴答作响?为每个按钮按下创建一个具有相同属性的新计时器()
实例(如果确实需要多个计时器)
保留一份所有计时器的列表是值得的,这样你就可以在不再需要它们时处理它们(这样,如果有人滥发了按钮,你就不会有几十个计时器了)。好吧,这取决于你是否需要跟踪所有这些计时器。如果不是,那就相当简单了。每次单击按钮时,只需创建一个计时器:
func buttonDidClick() {
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
}
如果需要跟踪这些计时器,请使用阵列:
func buttonDidClick() {
myArray.append(Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true))
}
这样,您甚至可以取消所有计时器或执行任何需要的操作。基于您的代码:
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
我假设您在ViewController
中将timer
声明为实例变量,类似于:
class ViewController: UIViewController {
var timer: Timer?
@IBAction func tapped(_ sender: Any) {
timer?.invalidate()
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
}
@objc func clock() {
print("counting...")
}
}
因此,每次点击按钮,即使您使用的是相同的计时器
实例,它也会安排一个新的计时会话。在这种情况下,您应该做的是在为其分配timer.scheduledTimer
之前,每次执行timer
:
停止计时器再次启动,并请求将其从
它的运行循环
在按钮操作方法中,首先添加timer?.invalidate()
:
@IBAction func tapped(_ sender: Any) {
timer?.invalidate()
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.clock), userInfo: nil, repeats: true)
}
要跟踪各种计时器,您需要创建一个计时器数组(
[Timer]
),并创建一个TimerState
作为userInfo
对象传递到每个计时器中。然后,当调用updateTimer()
时,您可以将该计时器的状态作为timer.userInfo
访问并使用它。当计时器达到0
时,调用invalidate()
,并将其从计时器列表中删除
如果用户按下停止所有计时器按钮,则使用计时器
阵列停止所有活动计时器
按下启动计时器按钮3次可在控制台中产生以下输出:
如果您对现有的计时器实例执行操作,您只需覆盖它(因此,您为什么看不到“旧的”实例)。是否希望为每个按钮按下生成一个新的运行循环?如果是,那么这应该是您代码的默认行为…假设我将两个计时器都附加到数组中,那么我如何从这两个同时滴答作响的计时器中打印数据?您可以在数组中循环,使用timer.invalidate()停止所有计时器,并使用timer.scheduledTimer再次实例化它们(用户每次单击按钮时都应执行此操作)。
import UIKit
class TimerState {
let number: Int
var count: Int
init(number: Int, count: Int) {
self.number = number
self.count = count
}
}
class ViewController: UIViewController {
var timerNumber = 1
var startingCount = 10
// Array to hold active timers so that all can be stopped
var timers = [Timer]()
@IBAction func startTimer(_ sender: UIButton) {
let state = TimerState(number: timerNumber, count: startingCount)
let timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer), userInfo: state, repeats: true)
timers.append(timer)
timerNumber += 1
}
@objc func updateTimer(_ timer: Timer) {
guard let state = timer.userInfo as? TimerState else { return }
state.count -= 1
if state.count == 0 {
print("Timer \(state.number) is done")
timer.invalidate()
// remove this timer from the list of active timers
if let index = timers.firstIndex(of: timer) {
timers.remove(at: index)
}
} else {
print("Timer \(state.number): \(state.count)")
}
}
@IBAction func stopAllTimers(_ sender: UIButton) {
for timer in timers {
guard let state = timer.userInfo as? TimerState else { continue }
print("Timer \(state.number) stopped")
timer.invalidate()
}
}
}
Timer 1: 9
Timer 1: 8
Timer 1: 7
Timer 2: 9
Timer 1: 6
Timer 2: 8
Timer 1: 5
Timer 2: 7
Timer 3: 9
Timer 1: 4
Timer 2: 6
Timer 3: 8
Timer 1: 3
Timer 2: 5
Timer 3: 7
Timer 1: 2
Timer 2: 4
Timer 3: 6
Timer 1: 1
Timer 2: 3
Timer 3: 5
Timer 1 is done
Timer 2: 2
Timer 3: 4
Timer 2: 1
Timer 3: 3
Timer 2 is done
Timer 3: 2
Timer 3: 1
Timer 3 is done