4

I have a NSTimer() that starts upon a button click. If I want the timer to be displayed on a label, I can do that within the same view controller, but I would like the timer to continue and the values (1...2...3) to be displayed on the next view controller. I have a label that displays the time variable on the next view controller but it only displays the value of the time variable when the button is pressed and does not continue. The time variable is passed but the function that runs it is not. How can I go about doing that?

var timer = NSTimer()

var time = 0

inside viewDidLoad :

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

    func timerFunc() {

        time++

//time label displays the time (1..2...3 etc)

        timeLabel.text = String(time)

    }

SecondSceneViewController has a time variable that is passed from this view controller:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            var secondScene = segue.destinationViewController as!           
                              SecondViewController

            secondScene.time = time
    }

When I go to the secondViewController, the value inside the time variable is whatever the time variable was when the button was pressed and it does not continue running. How would I go about passing the timer to the next view controller to display the values?

IvOS
  • 323
  • 3
  • 13

3 Answers3

5

IMO you should extract the code for the timer into a Singleton and then access it from both ViewControllers

Here's a simple one to get you started:

class TimerManager {

var realSharedInstance: TimerManager?
var sharedInstance: TimerManager {
    get{
        if let realSharedInstance = realSharedInstance {
            return realSharedInstance
        }
        else{
            realSharedInstance = TimerManager()
            return realSharedInstance!
        }
    }
}

var timer: NSTimer

init() {
    timer = NSTimer()
}

func rest() {
    timer = NSTimer()
}

}

GetSwifty
  • 7,568
  • 1
  • 29
  • 46
3

I would create a singleton that will handle the timer event.

    let myTimerNotificationNameKey = "timerKey"
    let myTimerNotificationUserInfoTimeKey = "timerUserInfoKey"

    class myTimer {
      static let sharedInstance = myTimer()
      var timer: NSTimer
      var time = 0

      func startTimer() {
         time = 0
         timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerFunc:", userInfo: nil, repeats: true)

      }

      func stopTimer() {
        timer.invalidate()
        timer = nil
      }

      func timerFunc(timer: NSTimer) {
            NSNotificationCenter.defaultCenter().postNotificationName(myTimerNotificationNameKey,object: nil, userInfo: {myTimerNotificationUserInfoTimeKey: time++})

      }
    }

On the first view controller you call myTimer.sharedInstance.startTimer() function that will start the timer. But first remember to listen to the notifications. The notification will receive a user info dictionary with the time count. Do the same thing on the second view controller.

Now you have a count that you can listen across multiple view controllers. Remember to stop the timer once you stop needing it.

Note: I haven't compiled this code.

carlos
  • 2,624
  • 4
  • 26
  • 36
  • @carlos-e-hernandez And how do you continue from that? Where would you init the myTimer class? – boehmatron Aug 16 '17 at 19:30
  • @boehmatron myTimer class can be accessed using the `sharedInstance` static method, which makes this class a singleton. You can access it everywhere. Not the best design, but resolves the issue the OP has. One other solution is to use dependency injection, have a class own myTimer, and then inject myTimer on every view controller that needs access to it. – carlos Aug 16 '17 at 22:43
0

If you keep these two variables

var timer = NSTimer()
var time = 0

outside the class they become global and you can access them from another view controller.

like this example:

import UIKit
import CoreData

var fromJSON = true

// Retreive the managedObjectContext from AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

class CoreDataController: UIViewController {

Another option would be working with a notification center:

NSNotificationCenter.defaultCenter().addObserver(
    self,
    selector: "batteryLevelChanged:",
    name: UIDeviceBatteryLevelDidChangeNotification,
    object: nil)

@objc func batteryLevelChanged(notification: NSNotification){     
    //do stuff
}
Ramsy de Vos
  • 1,053
  • 15
  • 21