I am fairly new to Obj-C programming, so please bear with me.
I have a Tab Bar. 1 of the tabs has a table view controller that gets it's data from an SQL database into an array.
In another tab it has a button to reset everything (delete all data). The view controller for this tab successfully deletes the SQL database, however the table is still full of data when going back to the table tab.
How can I unload the table view controller from memory when the button is pressed from this other view controller?
If I simulate a memory warning, then the table clears and is rebuilt when going back to the tab. This is what I am trying to do in code.
Thanks
You need to call reloadData on that UITableView.
It is cleared during memory warning, cause a view controller recreates its own view every time it receives this warning (in case it is not currently visible).
I think you could accomplish this using NSNotifications.
In the init method of your 1st view controller put this code:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(tableViewDataUpdated:)
name:#"DATA_UPDATED"
object:nil];
Create a tableViewDataUpdated method that reloads the array containing the data, and then calls reload on the table view.
In the 2nd view controller, when sql data base gets cleared, call
NSNotification *notification = [NSNotification notificationWithName:#"DATA_UPDATED" object:nil userInfo:nil];
[[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP];
Finally in the dealloc method of the 1st view controller include:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Related
What I would specifically like to do is test in a view controller X's view will appear method
if ('view controller X' is the first responder) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(TestSelector2:) name:UIApplicationDidBecomeActiveNotification object:nil];
}
'view controller x' in the above example code is nothing but 'self', I used view controller x for clarity
because currently every view controller I have subscribing to the UIApplicationDidBecomeActiveNotification is getting called and they are each calling theire respective methods. I would only like one view controller to be notified that the application became active at a time, the view controller I would like to be notified should always be the one visible to the user (the first responder). Can someone help, I am new to IOS dev
Thanks
If you're using a navigation controller you can access it using navigationController.visibleViewController
My app has two tabs, one of which is a table view, in the other tab I can add the current object to the core data storage, and I wish the table view could be up-to-date anytime I am done adding and switch back to that tab (table view). Currently, the table view only refreshes when my app relaunches which is understandable, because I am getting the data in the viewDidLoad method in that viewController. When I switch back and forth between these two tabs, their views are already loaded, so how can I update the table view in realtime? Any advice would be appreciated.
Update:
A good example is the contact app on iphone, but I don't know how to do that...
Here is some code in the table view controller.
- (void)viewDidLoad {
[super viewDidLoad];
bList = [[NSMutableArray alloc] init];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//some code to get data from core data storage and put them in the bList array.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveAddNotification:)
name:#"AddNotification"
object:nil];
}
-(void) receiveAddNotification: (NSNotification *)notification{
if ([[notification name] isEqualToString:#"AddNotification"]){
NSLog (#"Successfully received the add notification!");
}
}
Code in the other tab's view controller.
-(IBAction) addSomething {
[[NSNotificationCenter defaultCenter] postNotificationName:#"AddNotification" object:self];
//some code to store an object in core data.
}
The console can output the message "Successfully received the add notification!", which means the notification works fine, but the table view didn't get refreshed when I switch back to the table view tab from edit tab. I'm assuming the newly added object in addSomething method should be updated to the receiveAddNotification: method either.
Hi Michael as I understand your question, You can use notifications concept. Start notification service in the table view controller and when you are done with adding the things you can post the notification so that, that will update the table view automatically.
Look in to the NSNotificationCenter.
Let me explain with an example.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveTestNotification:)
name:#"TestNotification"
object:nil];
add the above statement in the table view controller. Then you just define the "receiveTestNotification:" function with [tableview reload];
And in the editing view controller when user taps the done button you post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"TestNotification" object:self];
So it will call the "receiveTestNotification:" method and run the code what ever you gave in that method.
I have one view class. In this class I have table view. In my model class I make Asynchrous ASIHTTPRequest. And I want when the operation is successful to reload data in table view. Which is good way to do this. I consider add one UITableView property to model class and use reload it. Is this good approach?
Make your model post notification to NSNotificationCenter and your table view register for this notification and reloadData when it receives one.
Inside your model, when changes occur:
[[NSNotificationCenter defaultCenter] postNotificationName:#"uniqueNotificationName"
object:self];
Inside your table view controller, register for notification, for example in viewDidAppear:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(methodToCall:)
name:#"uniqueNotificationName"
object:nil];
And implement methodToCall:
- (void)methodToCall:(NSNotification *)notification {
[self.tableView reloadData];
}
When you are done with the table view, for example in viewWillDisappear: you need to unregister for notifications:
[[NSNotificationCenter defaultCenter] removeObserver:self];
I think your model should inform te controller that is has updated (or other way around using KVO). The controller should then message the view to reload.
When you want to reload table view you can use one of this approaches:
If you want to reload all displayed cells then you can just call [tableView reloadData];. Notice, that only displayed cells will be reloaded. So if you have, for example, 10000 cells and only 10 of them are displayed, then only for 10 cells will be recalled method cellForRowAtIndexPath:.
If you want to reload particular cells then you should call following method of UITableView : - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation and provide in first operand list of cells to reload.
If you want to reload whole section (or number of sections) of UITableView then you should call - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation and provide in first operand list of sections to reload.
Hope, it will help you to choose appropriate variant.
use synchrous and gcd to load data.
when receive data call [self reload] on main queue
I'm trying to unload a view controller from view when the iPhone goes to sleep. My app has a stopwatch that has to keep counting when the phone goes to sleep or call comes in or the user closes the app without logging out.
I have all this functionality in place, I'm capturing all start times and stop times and upon re-entering the stopwatch view controller, I calculate the difference. It all works beautifully. When I was doing some additional testing I realised I hadn't catered for the iPhone going into sleep mode.
So all I need to do to make sure my stopwatch is correct bring the user back to the app home screen. I know the following method is called when the app goes to sleep:
-(void)applicationWillResignActive:(UIApplication *)application
How do I unload the stopwatch view controller from my app delegate ?
---- UPDATE ----
kpower, thanks for your feedback. I've implemented the following code:
In my App Delegate:
- (void)applicationWillResignActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"AppIsAsleep" object:nil];
}
In my view controller, I have the following:
-(void)viewDidLoad
{
// Add Observer.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(viewDidUnload:) name:#"AppIsAsleep" object:nil];
}
- (void)viewDidUnload {
//Remove the Observer.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"AppIsAsleep" object:nil];
}
When the phone goes to sleep, it actually closes the app, am I doing something wrong ?
Regards,
Stephen
You can use the Notifications mechanism. It allows you to unload view controller from different place (not the AppDelegate) this case.
For example, in your view controller's viewDidLoad method you add an observer (don't forget to remove it in viewDidUnload) and in applicationWillResignActive: method of AppDelegate you just simply post notification. That's all.
↓ Update here ↓
When you get a notification - you should manage view controller's removing by yourself. And calling viewDidUnload here is not the solution, cause this method is called after view controller was already unloaded and doesn't cause removing.
How to remove? Depends on how the view controller was added (for example, popViewControllerAnimated for UINavigationController). The main idea here is to make object's retain count equal to 0 (as you know this case an object will be destroyed) - so you should sent release message necessary amount of times.
I am using a navigation based application for iPhone. I want to reload a view when i come back to it after pressing the back button. ANy solution?
Regards
Add a method viewWillAppear: to your controller class. In that method you can then update the view with current data.
The viewWillAppear: method will execute whenever the view is about to be displayed (after navigating to a different view using UINavigationController)
There is more than one, but I usually use NSNotificationCenters. You attach "listeners" for some kind of event, like this:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(onSomethingChanged:)
name: #"somethingChangedEvent"
object: nil];
So, if some other view changes a setting, it notifies all the listeners like this:
[[NSNotificationCenter defaultCenter] postNotificationName: #"somethingChangedEvent" object: Nil];
Pretty simple and intuitive.