I was wondering is it possible to update the text label of a timer in a today widget. I took a look around but nothing helped me.
Asked
Active
Viewed 4,674 times
9
-
I think that the only way to do it is to pass the NSTimeInterval of the main view controller and create another timer in the today widget. I'll figure out a way :] – Nicholas Jan 19 '15 at 07:58
2 Answers
13
Yes you can. I have just tested and it works. You just have to add your timer to the main run loop NSRunLoopCommonModes:
RunLoop.main.add(yourTimerName, forMode: .commonModes)
import NotificationCenter
class TodayViewController: UIViewController, NCWidgetProviding {
@IBOutlet weak var strTimer: UILabel!
var timer = Timer()
func updateInfo() {
strTimer.text = Date().description
}
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateInfo), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: .commonModes)
}
func widgetPerformUpdate(completionHandler: @escaping (NCUpdateResult) -> Void) {
completionHandler(.newData)
}
}

Leo Dabus
- 229,809
- 59
- 489
- 571
-
thanks for your answer I have to put that in my code since my timer is running in the main view controller and I'm trying to pass that timer from the view controller to the todayviewcontroller using NSUserDefaults and groups – Nicholas Jan 19 '15 at 07:21
-
feel free to open another question with your code I will take a look at it for you – Leo Dabus Jan 19 '15 at 07:26
-
the problem is that it is not possible to put timer objects into NSUserDefaults... just try to put the timer in the Main View Controller in your code and call it back to the today widget... :] – Nicholas Jan 19 '15 at 07:29
-
Passing a timer object between the app and its extension doesn't make a lot of sense. Why can't the extension create its own timer object? – Tom Harrington Jan 19 '15 at 17:29
-
@TomHarrington because I want to see the same timer in the main app and in the today widget and I cannot do that in anyway, I cannot pass either a NSTimer or NSTimerInterval. Why? – Nicholas Jan 19 '15 at 20:26
-
@Nicholas as I said that's another question. Go ahead and open a new question. – Leo Dabus Jan 19 '15 at 20:28
-
@LeonardoSavioDabus I think I did it! At the moment I'll give a positive answer, thank you so much. I might open another question! – Nicholas Jan 19 '15 at 20:39
-
@Nicholas as I said, passing the `NSTimer` doesn't make sense. An `NSTimer` only calls a method on an object, and objects can only exist in one process. Even if you could pass the `NSTimer` it would serve no purpose. It should be possible to save an `NSTimeInterval` to user defaults though, if you need to pass a value back and forth. – Tom Harrington Jan 19 '15 at 21:41
-
@TomHarrington when I'll publish my app I'll show you why I need that. Thanks anyway – Nicholas Jan 20 '15 at 08:34
-
2It would be **extremely** interesting to hear why you think you need to pass an `NSTimer` object between two processes, and why using an `NSTimeInterval` is not sufficient. – Tom Harrington Jan 20 '15 at 16:57
-
1This is not true I don't even open my app and I can see the timer running – Leo Dabus Jan 24 '15 at 15:03
-
this solution works quite good, but the only problem is about the `viewDidLoad()` method, this method is called every time the user swipe to the "Today View Screen". **So multiple timer was scheduled**. One for each time u swipe to the "Today View Screen" ... – Mike D3ViD Tyson Aug 01 '19 at 00:16
-
There is only one timer instance.You can simply invalidate() the timer to make sure you don't add it twice to the run loop – Leo Dabus Aug 02 '19 at 18:27
-
-
4
I know this is a Swift question, but I found it looking for Objective-C code and so others may too.
-(void) viewDidLoad
{
[NSTimer scheduledTimerWithTimeInterval:1 // update more than once a second to appear in sync with the system clock
target:self
selector:@selector(updateUi:)
userInfo:nil
repeats:YES];
}
-(void) updateUi:(NSTimer *)timer
{
// Update Widget UI as required
}

lewis
- 2,936
- 2
- 37
- 72
-
No need to increase the interval to make it appear in sync. You can schedule the timer to fire at the next even second. – Leo Dabus Jul 30 '20 at 03:44
-
-
This shows how to do it without the seconds but you can easily change to sync the seconds. https://stackoverflow.com/a/61299018/2303865 – Leo Dabus Jul 30 '20 at 13:56