我正在创建一个用户得分的游戏,需要更新计时器倒数,使其增加2秒。我似乎无法正常工作。在线其他解决方案表示,我需要使当前计时器无效并创建一个新计时器。我怎样才能做到这一点?计时器从15秒开始,我需要在if条件语句中加上2秒。
@objc func counter(){
seconds -= 1
countDownLabel.text = String(seconds)
if (seconds == 0){
timer.invalidate()
}
}
func updatetimer(){
seconds += 2
}
func activatetimer(){
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.counter), userInfo: nil, repeats: true)
}
答案 0 :(得分:1)
我建议使用DispatchSource
计时器,该计时器可以在添加秒数之前 可靠地重新启动。如果秒数已过期,则不会发生任何事情。
var timer : DispatchSourceTimer?
func activatetimer() {
if timer != nil { return }
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer!.schedule(deadline:.now() + .seconds(1), repeating: 1.0)
timer!.setEventHandler {
self.seconds -= 1
DispatchQueue.main.async {
self.countDownLabel.text = String(self.seconds)
}
if self.seconds == 0 {
self.timer?.cancel()
self.timer = nil
}
}
timer!.resume()
}
func updatetimer(){
if let timer = timer {
timer.schedule(deadline:.now() + .seconds(1), repeating: 1.0)
seconds += 2
}
}
答案 1 :(得分:1)
Timer
并不是解决问题的关键,Timer
只是一个“检查”整个运行时间的机会。
真正的关键是知道Timer
已经运行了多长时间以及应该允许运行多长时间(即持续时间),由此您可以计算出还剩下多少时间。
然后,您无需任何其他操作即可更改持续时间。
请注意,我的计时器正在减少
这无关紧要。基本上,您有几条信息...
您知道:Timer
的启动时间
您可以计算:计时器已运行的时间(开始时间与现在的时间之差)
您可以计算:剩余时间(运行时间与允许的持续时间之差)
这仅仅是基本的时间/持续时间功能。 Timer
只是为您提供了一种手段,可以定期“检查”计时器的运行时间
...作为“粗略”示例...
var startedAt: Date?
var duration: TimeInterval = 5.0
var timer: Timer?
// This is just the label you want to update
@IBOutlet weak var durationLabel: UILabel!
// Convince duration formatter
var durationFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second]
formatter.unitsStyle = .abbreviated
return formatter
}()
// Stop the clock
func stop() {
timer?.invalidate()
timer = nil
startedAt = nil
}
// Start the clock
func start() {
stop() // Just make sure
startedAt = Date()
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(tick(_:)), userInfo: nil, repeats: true)
}
// The check in
@objc func tick(_ timer: Timer) {
// Is the timer running?
guard let startedAt = startedAt else {
stop()
return
}
// How long has the timer been running
let runningTime = Date().timeIntervalSince(startedAt)
// Has time run out yet
if runningTime >= duration {
durationLabel.text = "Time ran out"
stop()
} else {
// Update the label with the remaining amount of time...
durationLabel.text = durationFormatter.string(from: duration - runningTime)
}
}
// Add more time to the duration...
@IBAction func moreTime(_ sender: Any) {
duration += 2.0
}
这是经过稍微修改的版本,用于在Playground中测试创意
import UIKit
import PlaygroundSupport
class Clock {
var startedAt: Date?
var duration: TimeInterval = 10.0
var timer: Timer?
var durationFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second]
formatter.unitsStyle = .abbreviated
return formatter
}()
func stop() {
timer?.invalidate()
timer = nil
startedAt = nil
}
func start() {
stop()
startedAt = Date()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(tick(_:)), userInfo: nil, repeats: true)
}
@objc func tick(_ timer: Timer) {
report()
}
func report() {
guard let startedAt = startedAt else {
stop()
return
}
let runningTime = Date().timeIntervalSince(startedAt)
print(">> Duration = \(duration); Running time = \(runningTime)")
if runningTime >= duration {
print("Time ran out")
PlaygroundPage.current.needsIndefiniteExecution = false
stop()
} else {
print(durationFormatter.string(from: duration - runningTime))
}
}
func moreTime(_ sender: Any) {
duration += 2.0
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
let clock = Clock()
clock.start()
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 2.0) {
print("++")
clock.moreTime("")
clock.report()
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 2.0) {
print("++")
clock.moreTime("")
clock.report()
}
}
当我运行它时,它输出...
>> Duration = 10.0; Running time = 1.0034409761428833
Optional("8s")
>> Duration = 10.0; Running time = 2.0030879974365234
Optional("7s")
++
>> Duration = 12.0; Running time = 2.018252968788147
Optional("9s")
>> Duration = 12.0; Running time = 3.002920985221863
Optional("8s")
>> Duration = 12.0; Running time = 4.002920985221863
Optional("7s")
++
>> Duration = 14.0; Running time = 4.035009980201721
Optional("9s")
>> Duration = 14.0; Running time = 5.003154993057251
Optional("8s")
>> Duration = 14.0; Running time = 6.002910017967224
Optional("7s")
>> Duration = 14.0; Running time = 7.002930045127869
Optional("6s")
>> Duration = 14.0; Running time = 8.003202080726624
Optional("5s")
>> Duration = 14.0; Running time = 9.002938032150269
Optional("4s")
>> Duration = 14.0; Running time = 10.002840995788574
Optional("3s")
>> Duration = 14.0; Running time = 11.002991080284119
Optional("2s")
>> Duration = 14.0; Running time = 12.002726078033447
Optional("1s")
>> Duration = 14.0; Running time = 13.003712058067322
Optional("0s")
>> Duration = 14.0; Running time = 14.002851009368896
Time ran out
如您所见,每次调用moreTime
(查找++
输出)时,都会将2秒添加到duration
中。 Clock
以10秒开始,但最终总共运行了14
秒