The problem you describe is caused by the current local notification: While the notification is handled, it is still in the list of scheduled notifications, so refreshing the table view will have no effect. A solution to this problem is to defer reloading the table view until after the notification is handled, something like
// In your app delegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.localNotificationsController reloadDataIfNeeded];
});
}
// In your controller that shows the local notifications
- (void)reloadDataIfNeeded
{
if (![self isViewLoaded]) return;
[self.tableView reloadData];
}
You could also delete the notification from the list if you only use notifications that only fire once (so that you are sure that the notification will disappear anyway):
// In your app delegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[application cancelLocalNotification:notification];
[self.localNotificationsController reloadDataIfNeeded];
}
As to the second part of your question ("how can I push a specific view after the notification is displayed (when the user slides the app icon when the phone is locked?"), there are two scenarios how an application can be activated by a local notification.
- Your application was suspended, but still in memory. Then selecting the local push notification will make the app enter the foreground,
-application:didReceiveLocalNotification:
will be called, and [application applicationState]
will be UIApplicationStateInactive
Your application is not running, i.e. not suspended, not in memory. Then you will receive the local notification in the launchOptions
in -application:didFinishLaunchingWithOptions:
:
UILocalNotification *localNotification = [launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
Despite what the documentation says, -application:didReceiveLocalNotification:
will not be called in this case.
So to show the notification that woke up the application, you can push your controller in these two cases.