Reputation: 1409
I have an application that has a label that is being used to display what is essentially a timestamp. Basically, when the user launches my app the start page has 3 buttons. The timestamp label will be displayed over the button that was used last (e.g. Last workout: Yesterday or Last workout: 2 days ago).
The label's string is compared to a date that was saved via UserDefaults to the current date to get the difference (e.g. Today, Yesterday, 2 days ago, 10 days ago, 32 days ago, etc.). I have the function to run this check and update the label happening in every place I can think to put it in order to have it update whenever the app is launched: viewWillAppear
, viewDidAppear
and viewDidLoad
The problem is that the app doesn't always reload when it's launched because iOS keeps it "open" in the background. So my label doesn't get updated unless I change tabs and go back to this start tab so the viewWillAppear
is called. That said sometimes, for some reason, it does actually reload displaying the splash screen again, not all the time and I don't know why it does this when it does...
Is there anything I can do to force my label to reload or run the function whether or not viewWillAppear
, viewDidAppear
, and viewDidLoad
is called?
Thank you!
Upvotes: 2
Views: 907
Reputation: 6009
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
Upvotes: 3
Reputation: 27
Use observer receiver pattern in applicationWillEnterForeground to update the label.
Upvotes: 0
Reputation: 2253
The app sometimes reloads the splash screen because the iPhone automatically closes apps in the background that are using too much memory. So if you background an app and do something memory intensive, you can expect the app to refresh when you go back to it.
How does IOS manage memory of backgrounded apps?
There is a delegate method in appDelegate that notifies the app when user has backgrounded or foreground the app. You can listen to this with a notification and reload your label when user enters foreground.
func applicationWillEnterForeground(_ application: UIApplication) {
}
Upvotes: 0
Reputation: 309
In the app delegate you can call
func applicationWillEnterForeground(_ application: UIApplication) {
}
This is called whenever the app is opened
Upvotes: 0