代码之家  ›  专栏  ›  技术社区  ›  Pandu Arif Septian

如何在swift中暂停和恢复NSTimer.scheduledTimerWithTimeInterval?

  •  31
  • Pandu Arif Septian  · 技术社区  · 11 年前

    我正在开发一个游戏,我想创建一个暂停菜单。这是我的代码:

    self.view?.paused = true
    

    但是 NSTimer.scheduledTimerWithTimeInterval 仍在运行。。。

     for var i=0; i < rocketCount; i++ {
        var a: NSTimeInterval = 1
        ii += a
        delaysShow = 2.0 + ((stimulus + interStimulus) * ii)       
        var time3 = NSTimer.scheduledTimerWithTimeInterval(delaysShow!, target: self, selector: Selector("showRocket:"), userInfo: rocketid[i], repeats: false)
     }
    

    我想要 time3 当玩家点击暂停菜单时暂停计时器,当玩家回到游戏时继续运行计时器,但我如何暂停 NSTimer.scheduledTimerWithTimeInterval ? 请帮帮我。

    9 回复  |  直到 7 年前
        1
  •  52
  •   pjtnt11    10 年前

    您需要使其无效并重新创建。然后可以使用 isPaused 如果您有相同的按钮来暂停和恢复计时器,bool将跟踪状态:

    var isPaused = true
    var timer = NSTimer()    
    @IBAction func pauseResume(sender: AnyObject) {     
        if isPaused{
            timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("somAction"), userInfo: nil, repeats: true)
            isPaused = false
        } else {
            timer.invalidate()
            isPaused = true
        }
    }
    
        2
  •  9
  •   Sushil    10 年前

    要开始:

    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateView"), userInfo: nil, repeats: true)
    

    要继续:

    timer=NSTimer.scheduledTimerWithTimeInterval(1.0,target:self,selector:selector(“updateView”),userInfo:nil,repeats:true)
    

    要暂停:

    timer.invalidate
    

    这对我有用。诀窍是不要寻找类似的东西 "timer.resume" "timer.validate" 。只需使用 “启动计时器的代码相同” 以在暂停后恢复。

        3
  •  9
  •   Rashid KC    9 年前

    开始

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
    

    暂停

    timer.invalidate()
    

    要重置

    time += 1
    label.text = String(time)
    

    “label”是输出上的计时器。

        4
  •  8
  •   stelf    7 年前

    我刚解决了游戏中的一个类似问题,找到了一个简单的解决方案。

    首先,我应该像其他人一样指出,Timer和NSTimer没有暂停功能。您必须使用Timer.invalidate()停止计时器。使计时器无效后,必须再次初始化它以启动计时器。引用自 https://developer.apple.com/documentation/foundation/timer ,函数.invalidate()-

    停止计时器再次启动,并请求从 它的运行循环。


    要暂停计时器,我们可以使用timer.fireDate,这是timer(和NSTimer)保存计时器将来何时启动的日期。

    下面是我们如何通过保存计时器在再次启动之前的剩余秒数来暂停计时器。

    //The variable we will store the remaining timers time in
    var timeUntilFire = TimeInterval()
    
    //The timer to pause
    var gameTimer = Timer.scheduledTimer(timeInterval: delaysShow!, target: self, selector: #selector(GameClass.showRocket), userInfo: rocketid[i], repeats: false)
    
    func pauseTimer()
    {
        //Get the difference in seconds between now and the future fire date
        timeUntilFire = gameTimer.fireDate.timeIntervalSinceNow
        //Stop the timer
        gameTimer.invalidate()
    }
    
    func resumeTimer()
    {
        //Start the timer again with the previously invalidated timers time left with timeUntilFire
        gameTimer = Timer.scheduledTimer(timeInterval: timeUntilFire, target: self, selector: #selector(GameClass.showRocket), userInfo: rocketid[i], repeats: false)
    }
    

    注: 在获取fireDate之前,不要使计时器无效()。调用invalidate()后,计时器似乎将fireDate重置为2001-01-01 00:00:00+0000。

    第二条注释: 计时器可能会在其设置的fireDate之后启动。这将导致一个负数,这将默认计时器在0.1毫秒后运行。 https://developer.apple.com/documentation/foundation/timer/1412416-scheduledtimer

        5
  •  4
  •   Christos Chadjikyriacou    11 年前

    为了阻止它

      time3.invalidate() 
    

    重新开始

      time3.fire()
    
        6
  •  4
  •   nickeyzzz    10 年前

    您无法恢复计时器。 与其继续,不如创建一个新的计时器。

    class SomeClass : NSObject { // class must be NSObject, if there is no "NSObject" you'll get the error at runtime
    
        var timer = NSTimer()
    
        init() {
            super.init()
            startOrResumeTimer()
        }
    
        func timerAction() {
            NSLog("timer action")
        }
    
        func pauseTimer() {
            timer.invalidate
        }
    
        func startOrResumeTimer() {
            timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("timerAction"), userInfo: nil, repeats: true)
        }
    }
    
        7
  •  3
  •   Béatrice Cassistat    8 年前

    尽管这里展示的解决方案很好,但我认为缺少一个重要的洞察力。就像这里很多人解释的那样,计时器无效()和重新创建是最好的选择。但有人会说你可以这样做:

    var paused:Bool
    
    func timerAction() {
        if !paused {
            // Do stuff here
        }
    }
    

    更容易实施,但效率会降低。

    出于能源影响的原因,苹果提倡尽可能避免使用计时器,并倾向于使用事件通知。 如果您确实需要使用计时器,则应通过使当前计时器无效来有效地实现暂停。在此处阅读《苹果能效指南》中有关计时器的建议: https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/MinimizeTimerUse.html

        8
  •  2
  •   Elio Lako    7 年前

    瑞士法郎3

    全球宣言:

     var swiftTimer = Timer()
     var count = 30
     var timer = Timer()
     @IBOutlet weak var CountDownTimer: UILabel!
    

    视图DidLoad

    override func viewDidLoad() { super.viewDidLoad() BtnStart.tag = 0 }

    触发的IBACTION:

    @IBAction func BtnStartTapped(_ sender: Any) {
          if BtnStart.tag == 0 {
               BtnStart.setTitle("STOP", for: .normal)
               timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ScoreBoardVC.update), userInfo: nil, repeats: true)
    
               BtnStart.tag = 1
          } else {
    
               BtnStart.setTitle("START", for: .normal)
               timer.invalidate()
    
               BtnStart.tag = 0
          }                    
     }
    

    处理以下事项的函数:

    func update(){
    
          if(count > 0){
               let minutes = String(count / 60)
               let ConvMin = Float(minutes)
               let minuttes1 = String(format: "%.0f", ConvMin!)
    
               print(minutes)
               let seconds = String(count % 60)
               let ConvSec = Float(seconds)
               let seconds1 = String(format: "%.0f", ConvSec!)
    
               CountDownTimer.text = (minuttes1 + ":" + seconds1)
               count += 1
          }          
     }
    
        9
  •  0
  •   Chetan Lodhi    9 年前

    暂停计时器:timer.invalidate()

    恢复计时器:重新创建计时器。工作很好。

    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(mainController.updateTimer), userInfo: nil, repeats: true)