在Swift中为timer添加值

gojuced7  于 2023-06-21  发布在  Swift
关注(0)|答案(2)|浏览(127)

我正在创建一个游戏,用户得分,计时器倒计时需要更新,以增加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)
}
az31mfrm

az31mfrm1#

我建议使用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
    }
}
vsdwdz23

vsdwdz232#

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示例...

这是一个稍微修改过的版本,用于在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(查找++输出)时,duration将增加2秒。Clock开始时为10秒,但最终总共运行了14

相关问题