How to refresh UITableView after app comes becomes active again? - iphone

I would like my UITableView to reloadData once my app is active again, after a user exits the application. I know I need to implement (in my app delegate):
- (void)applicationDidBecomeActive:(UIApplication *)application
but im not sure how to reference the current UITableView?
UPDATE:
My UITableView is a separate controller. It is actually presented as follows
AppDelegate > Root View Controller > Pushes UITabBarController modally which has a UITableViewController

following up on Ole's answer above
add this when initializing the viewcontroller
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
add the actual method in the controller
- (void)becomeActive:(NSNotification *)notification {
NSLog(#"becoming active");
}
be sure to clean up the notification
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}

If you can't access your view controller from the app delegate, you could also have your controller listen to the UIApplicationDidBecomeActiveNotification notification.

you can create your class called TableViewManager. in there register list of UITableView so that you can refresh any table you want.
it's like this, in yourTableViewManager class, you have a method called
- (void)RefreshTableView:(UITableView *)tableView {
if(tableView != nil)
[tableView reloadData]; }

Related

Adding an observer to each view or present view dynamically

I am posting a notification locally in the app when ever I receive a remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"Received notification: %#", userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:#"NEWMESSAGE" object:nil userInfo:userInfo]; }
I have added an observer to the view in the function viewWillAppear() and remove the observer in viewWillDisappear().
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(newMessageReceived:) name:#"NEWMESSAGE" object:nil];
and
[[NSNotificationCenter defaultCenter] removeObserver:self];
My question is I want to override every viewWillAppear and viewWillDisappear functions in all *.m files that use these functions in my app.
or how can I dynamically add an observer (like above) to the present view and remove the observer when that view disappears. it should be like a global action whenever view changes observer to be added and removed when it changes again.
Is this possible? if so please guide me.
thanks in advance.
Some thoughts:
You can subclass UIViewController and implement these method in the subclass-ed view controller class. Then you need to create all your views as the subclass of this UIViewController.
Example:
//Creating a custom subclass of UIViewController
#interface CustomViewController : UIViewController
#end
#implementation CustomViewController
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(newMessageReceived:) name:#"NEWMESSAGE" object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#end
And create all your view controller as the subclass of CustomViewController.

Dismiss popover when app goes in background

How to dismiss popover when application enters in background?
You can do this using the delegate method in appdelegate.m file
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//put your dissmiss popover code here
}
it is better to register your controller for UIApplicationDidEnterBackgroundNotification or UIApplicationWillResignActiveNotification and dismiss it whenever your app goes to background, this will make your life quite easier i feel.
registering for notification in your viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMethod)
name:UIApplicationDidEnterBackgroundNotification object:nil];
implement the method and
-(void)myMethod{
// dismiss popview here
}
finally un-register from the notification in your view controller
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Send an NSNotification in your app delegate's willResignActive method, and listen for it in your view controller that contains the popup, and have it dismiss said popover when the notification is received.
try this
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//[popover dissmissPopoverAnimated:YES];
}

Call [tableView reloadData]; on a viewController from a modalViewController

I have a modalViewController that comes up over the top of a viewController with a tableView. When the user clicks a button on the modalViewController I want to reload the tableView within the viewController with this:
[tableView1 reloadData];
I do not want to put the reload in the viewDidAppear or viewWillAppear methods as they get called when i do not need the tableView to reload (i.e. when the user clicks the back button to return to the tableView).
Is there a way to do this?
Try
1) write one method which reloads the table data.
2) Call it on the back button clicked.
This is the classic delegate pattern problem, in your modal view controller you need a delegate reference to the current view controller presenting it
//Modal
#protocol ModalVCDelegate
- (void)tappedBackButton;
#end
#class ModalVC: UIViewController
#property id<ModalVCDelegate> delegate;
#end
#implementation
- (void)backButtonTapped:(id)sender
{
if (self.delegate)
[self.delegate tappedBackButton];
}
#end
Now, in your presenting VC, just process this delegate message
//Parent VC
- (void)showModal
{
ModalVC *vc = [ModalVC new];
vc.delegate = self;
//push
}
- (void)tappedBackButton
{
[self.tableView reloadData];
//close modal
}
You can use delegate . If find it more harder then alternative is to use NSNotificationCenter. You can see accepted answer for Refreshing TableView. This is really very short, easy and understandable way.
using Notification like bellow Method:-
Create NSNotificationCenter at yourViewController's ViewdidLoad Mehod
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(ReloadDataFunction:)
name:#"refresh"
object:nil];
[super viewDidLoad];
}
-(void)ReloadDataFunction:(NSNotification *)notification {
[yourTableView reloadData];
}
Now you can Call this Notification from your modelViewController BackButton or else you want from calling this Refresh notification like putting this line of code:-
[[NSNotificationCenter defaultCenter] postNotificationName:#"refresh" object:self];
NOTE: postNotificationName:#"refresh" this is a key of particular Notification
Try to use this one
Make a Button and click on this button and than you can reload your data.
This button make custom and use it on background.
- (IBAction)reloadData:(id)sender
{
[tblView reloadData];
}
You can use NSNotification to refresh table on ViewController.
Inside viewController :
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
Write code in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reloadMainTable:)
name:#"ReloadTable"
object:nil];
- (void) reloadMainTable:(NSNotification *) notification
{
[tableView reload];
}
Inside ModelViewController:
[[NSNotificationCenter defaultCenter]
postNotificationName:#"ReloadTable"
object:nil];
Here you can also send custom object instead of nil parameter. But be care full about removal of NSNotification observer.

Reload UITableView from another tab

I am having trouble trying to reload UITableView cell data which are being loaded from an XML source.
Here is the scenario. App contains tabs, in one of them there is a tableview which gets it's data from an XML file and works just ok, but the thing is when I want to change the feed category and change the XML from another tab I can refresh the current tableview.
For switching between tabs I use
self.tabBarController.selectedIndex = 1;
and pass the category feed to the other tab which I want to load
xmlParser = [[XMLParser alloc] loadXMLByURL:categories];
and it still loads the same old feed, not the new one which has been passed. I checked with NSLog and the feed value passes properly but it just wont load after switching.
I also tried to [self.tableView reloadData]; from both current tab and the category tab and it didn't work either.
You can use NSNotifications to send a notification from your other tab and have a oberver in your tableview that responds to that notification.
Example
(Tab calling the reload of the tableview) put this code whenever you want to reload the data, so when a button is pushed or a download is finished etc.
NSNotification * notification = [NSNotification notificationWithName:#"updateTable" object:nil];
[[NSNotificationCenter defaultCenter] postNotification:notification];
In the UITableViewController / the class with the UITableView, do the following.
in your viewDidLoad add:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateTableView) name:#"backtolist" object:nil];
Then add the function updateTableView
- (void) updateTableView: (NSNotification*) note
{
//Do whatever needs to be done to load new data before reloading the tableview
[_tableView reloadData];
}
Hope this helps
Ophychius was correct in his suggestion to use Notifications. I'm assuming you have all of the data sources for your table view updating when the XML is finished loading. This also assumes you're using dynamic cells. In the class that loads the XML, post a Notification when the new XML is finished loading.
[[NSNotificationCenter defaultCenter] postNotificationName:#"XMLLoaded" object:nil];
In the table view class, register as an observer for the Notification you posted from the XML class.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reloadTable:) name:#"XMLLoaded" object:nil];
As you can see, this calls a selector when this notification is received. Either call your method where you build the table, or create another simple method to call reloadData from.
-(void)reloadTable:(NSNotification *)notif
{
NSLog(#"In ReloadTable method. Recieved notification: %#", notif);
[self.tableView reloadData];
}
Finally (as Leonardo pointed out below), in your viewDidUnload (or dealloc for ios6) method, remove the class as an observer of that notification.
- (void)viewDidUnload
{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
I am just guessing, without having seen the rest of the code.
I suppose your table view has an NSArray datasource, did you make sure that your array datasource is updated too ? Does your xml parser, or controller, transfer those data to the NSArray ?
Because if you call reloadData it is just going to refetch the same array. And if it is not updated, you would get old data.

I expect the initial view controller of my storyboard to be the current controller

If the application was previously in the background, when applicationDidBecomeActive is called, I expect the initial view controller of my storyboard to be the current controller.
I used:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self.window makeKeyAndVisible];
}
When I restart app ,loginAciton inside rootViewController still be called ,but could not present the next controller . No errors like nothing happened.
- (IBAction)loginAciton:(id)sender
{
id controller = [self.storyboard instantiateViewControllerWithIdentifier:#"Navigation"];
[self presentModalViewController:controller animated:YES];
}
Why?
PS. My rootViewController is not a UINavigationController.
Thanks for any replies.
A much better way is to add UIApplicationExitsOnSuspend to your Info.plist and set it to YES.
I got it !
if you wanna the initial view controller of your storyboard to be the current controller every time , you can try it :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
exit(EXIT_SUCCESS);
}
You can use the notification too, put this code in applicationDidBecomeActive:
[[NSNotificationCenter defaultCenter] postNotificationName:#"appActivated" object:nil];
and add observer in that current view ...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateView:)
name:#"appActivated"
object:nil];
and don't forget to remove the observer in dealloc: of your current view...
[[NSNotificationCenter defaultCenter] removeObserver:self];
may this will help you..