Update Label Text with Timer Values
I see a few issues:
- The
finance
object goes out of scope whenfireTimer()
returns. It will be deallocated then. The timer will be setting a label text on a no longer existing view controller. - Instantiating a
UIViewController
withFinanceVC()
doesn't display it on screen. After instantiating you need to explicitly show. You can do this for example by calling present(_:animated:completion:) from a parent view controller. - The timer updates
dayLabelText
which does not updatedayLabel.text
Might be good to follow a basic YT tutorial on how to display a view controller.
Good luck, you'll get it soon enough!
How do I refresh a labels text
Use a Notification Observer pattern
First, set up a notification to know when the app will enter the foreground state:
func sceneWillEnterForeground(_ scene: UIScene) {
NotificationCenter.default.post(name: Notification.Name("sceneWillEnterForeground"), object: nil)
}
Note: As of iOS 13, the needed function is in the SceneDelegate file and not in AppDelegate.
Next, listen for that notification and respond by adding an observer where this type of notification is needed(such as in viewDidLoad()):
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: Notification.Name("sceneWillEnterForeground"), object: nil)
Note: The notification name must match the one you created in the SceneDelegate.swift file.
Lastly, create the selector mentioned above. Add code that will execute in response to the willEnterForeground notification:
@objc func willEnterForeground() {
// Update your label here
}
Note: The function name here must match the selector name above.
This link is to a small app that uses the notification-observer pattern should you feel a working example would be helpful:
https://github.com/PepperoniJoe/MusicWithColor
Updating time text label each minute in WidgetKit
A possible solution is to use the time
date style:
/// A style displaying only the time component for a date.
///
/// Text(event.startDate, style: .time)
///
/// Example output:
/// 11:23PM
public static let time: Text.DateStyle
- You need a simple
Entry
with aDate
property:
struct SimpleEntry: TimelineEntry {
let date: Date
}
- Create an
Entry
every minute until the next midnight:
struct SimpleProvider: TimelineProvider {
...
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
var entries = [SimpleEntry]()
let currentDate = Date()
let midnight = Calendar.current.startOfDay(for: currentDate)
let nextMidnight = Calendar.current.date(byAdding: .day, value: 1, to: midnight)!
for offset in 0 ..< 60 * 24 {
let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: midnight)!
entries.append(SimpleEntry(date: entryDate))
}
let timeline = Timeline(entries: entries, policy: .after(nextMidnight))
completion(timeline)
}
}
- Display the date using the
time
style:
struct SimpleWidgetEntryView: View {
var entry: SimpleProvider.Entry
var body: some View {
Text(entry.date, style: .time)
}
}
If you want to customise the date format you can use your own DateFormatter
:
struct SimpleWidgetEntryView: View {
var entry: SimpleProvider.Entry
static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "HH:mm"
return formatter
}()
var body: some View {
Text("\(entry.date, formatter: Self.dateFormatter)")
}
}
Here is a GitHub repository with different Widget examples including the Clock Widget.
iOS Swift Update text label after 1 second
You shouldn't use the sleep()
function as this will suspend the main thread and cause your app to become non-responsive. NSTimer
is one way to achieve this. It will dispatch a function at a specified time in the future.
For example -
var countdown=0
var myTimer: NSTimer? = nil
override func viewDidAppear(animated: Bool) {
countdown=5
myTimer = NSTimer(timeInterval: 1.0, target: self, selector:"countDownTick", userInfo: nil, repeats: true)
countdownLabel.text = "\(countdown)"
}
func countDownTick() {
countdown--
if (countdown == 0) {
myTimer!.invalidate()
myTimer=nil
}
countdownLabel.text = "\(countdown)"
}
How update a label periodically on iOS (every second)?
The problem is that a scheduledTimer will not get called while the main thread is tracking touches. You need to schedule the timer in the main run loop.
So instead of doing
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLabel:) userInfo:nil repeats:YES];
use
NSTimer* timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(updateLabel:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
Updating label takes too long (swift)
What happens is that code is probably run on a secondary thread. Any UI changes you make should be made on the main thread. So try this:
dispatch_async(dispatch_get_main_queue()) {
// update label
}
This should update your label instantly.
Updating Label Text several times while a Button is pressed in Swift
You can run all of your long-running tasks in a background queue, and make the label updates in the main queue. The key is to call the next function only when the first is finished, or they will run in parallel, and could all update at the same time. Here's an example
func doSomething1() {
// as good a way as any to simulate a long-running process
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text1"
}
DispatchQueue.global(qos: .background).async {
self.doSomething2()
}
}
func doSomething2() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text2"
}
DispatchQueue.global(qos: .background).async {
self.doSomething3()
}
}
func doSomething3() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text3"
}
DispatchQueue.global(qos: .background).async {
self.doSomething4()
}
}
func doSomething4() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text4"
}
}
@IBAction func cmdDoStuff(_ sender: UIButton) {
DispatchQueue.global(qos: .background).async {
self.doSomething1()
}
}
Related Topics
Match the Data Type of a Object in Swift
How to Properly Handle a Nil Uiapplication.Sharedapplication().Keywindow
Modifing One Variable from Another View Controller Swift
Game Exits from Pause State After Resuming It from Background in Swift
Ksecattrkeytypeec Causing Encryptmessagewithpublickey() to Fail
Match the Data Type of a Object in Swift
Skaction Works in Didmovetoview But Doesn't Works in Function
Swift Conform to Protocol Subclass
Using Huffman Coding to Compress Images Taken by the iPhone Camera
How to Fix Uilabel Text Spacing
How to Get Only Keys from Firebase
Deinit Method Is Not Called in Xcode 10 Beta 6 Playground
Google Cloud Messaging Bridging Header Import Fails
How to Send Emails in Swift Using Mailgun
Random Number from an Array Without Repeating the Same Number Twice in a Row