在Swift中为计时器添加值

时间:2018-06-24 09:17:30

标签: swift timer

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

2 个答案:

答案 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