I have an application with several UITableViewControllers.
Now, the user is allowed to change "Data source". In that case I need to invalidate (reset) data in the relevant UITableViews.
I figured out, that I can use NSNotificationCenter and add these controllers as observers to events which will be generated when the data source changes.
The question is, how do I reset the underlying tables? I can, of course, set some boolean flag, and call UITableView:reloadData in viewWillAppear or viewDidAppear, but I was wondering, if there's a cleaner way of doing it.
Or perhaps I'm completely missing the point, and I don't need NSNotificationCenter altogether.
Thank you very much in advance.
The question is, how do I reset the
underlying tables? I can, of course, set some boolean flag
I'm not sure why you need to use a flag here. When your view controller gets the notification, have it reload the table in the notification handler.
Updating your table will work a bit differently if your UITableView is attached to an NSFetchedResultsController. Is it?
Related
I have a TabBar Application with 2 tabs saving/fetching data to and from CoreData. The problem that I am having is that when the form has been filled and the user has touched the save button the view is not re-loaded or re-initialised. All I want is for the view to be ready for the user to repeat the process with the next set of information. I am probably not thinking about this in the correct way so a pointer in the right direction would be very much appreciated...
Do I need to manually set everything including the managedObjectContext etc. to nil? Or is there something that I can do with methods like viewWillDisappear that will elegantly help me to "re-initialise" that specific tab?
I ave read up the Apple docs on view hierarchies, and life cycles but I just seem to have confused myself...
Thanks in advance for any suggestions, referrals to code or even recommendations on relevant reading material.
It sounds like what you want to do is reload any data to their default states when the user taps a button. Unfortunately, you'll have to do this manually, setting each IBOutlet's value to a meaningful default (probably the empty string).
There are two ways I can think of that would help make this more elegant:
Use an IBOutletCollection and fast enumeration to loop over all the IBOutlets and not have a bunch of code to do each one individually.
If you're switching tabs in between these events, you can something neat and use your app delegate as your UITabBarControllerDelegate for the tabBarController:didSelectViewController: to call the clearing-out method for you instead of relying on viewDidAppear.
Any help would be appreciated.
I am looking for a way to programatically notified that a view is loaded from outside of that viewController.
Lets say my main view has 5 buttons, after the view is loaded and the buttons appeared I want to be notified in another file (outside of that viewContrller) that it is loaded. How/Where can I check this and be notified?
Do I need to do some Aspect Oriented Programming?
Use NSNotificationCenter. You can communicate between classes.
NSNotificationCenter or a delegate method is the most appropriate way to accomplish this.
Listen for a custom NSNotification inside your other object. Have your view controller post that notification during whichever part of its life cycle makes most sense (viewDidLoad, viewDidAppear ...).
If you can't post a notification, then observing a keyPath might be the way to go. For example, you can put something like this in your control object and then implement observeValueForKeyPath::
[viewController addObserver:self
forKeyPath:#"view"
options:NSKeyValueObservingOptionNew
context:NULL];
While you can do this with notifications as others have suggested or KVO, this strongly suggests a design problem. You should never be accessing a view controller's internal views directly. So the deeper question is: why do you want to know?
The most likely cause in my experience is that you're letting some other object set the titles or modify enabled. This breaks MVC and leads to the kind of problems you're probably trying to fix. The correct way to handle this is to put the data into a model object that is shared between the various view controllers. The current view controller can then observe changes on the model and update its UI elements appropriately.
In my UIView I've got a UITableView (UITV) which is controlled by an NSFetchedResultsController (NSFRC). The UIView is inside a UINavigationController.
When the view is about to be loaded/displayed I start some background activities which fetch data from a remote server (JSON) and parse into Core Data.
The NSFRC is being called when the parsing is done and the threaded NSManagedObjectContext have been merged into the main context.
The problem is that sometimes many rows are being inserted to Core Data at once, a lot of table cells are being added and there is quite a delay from that the actual fetching and parsing is done, until the rows are being displayed.
Now I wonder if anyone knows of any solution to, for example:
hook up a spinner to some "fetched results controller inserted all its rows for this time" (or something) notification/delegate call to at least tell the user that "something is going to show up soon"?
Or might the best solution simply be to not initialize the NSFRC until the background fetching and processing is completed?
Thanks!
If I understand your question correctly, you may want to look into the NSFetchedResultsControllerDelegate methods, with documentation available here: http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html
There are delegate methods available for pre changes with controllerWillChangeContent:, post changes with controllerDidChangeContent and during changes with didChangeSection: and didChangeObject.
I hope it helps!
Rog
I have been using Objective-C for a while and pretty much understand most of its features. However, the concept of delegates eludes me. Can someone please give a succinct and easy to comprehend explanation of what delegates are, how they are used in the iPhone SDK, and how I can best make use of them in my own code?
Thank you!
There are a couple main reasons to use delegates in Objective-C, which are subtly different:
Enhancing the base functionality of a framework class. For example, a UITableView is pretty boring on its own, so you can give it a delegate to handle the interesting bits (creating table cells, adding text to section headers, what have you). This way, UITableView never changes, but different table views can look and act very differently.
Communicating to parent objects in your dependency hierarchy. For example, you may have a view with a button that the user may push to do something that affects other views. The view will have to send a message to its parent view, or perhaps the view controller, so that it can create or destroy or modify other views. To do this you'd pass the parent object into your view, most likely through a protocol, as a weak reference (in Objective-C, an assign property). The view could then send any message declared in the protocol to the parent, or delegate, object.
This approach need not involve views. For example NSURLConnection passes event back to its delegate, which may be the object that created it, using this mechanism.
Essentially, all a delegate is, is an object that accepts feedback from another object. Put simply, when stuff happens to an object, it tells its delegate (assuming it has one).
For instance, lets say I have a UIViewController with a UITextView placed in the middle of the view. I set up my UIViewController to be the delegate of the UITextView. Then, when certain actions are performed on the text view (begin editing, text changes, end editing, etc), it tells it's delegate so it can do whatever logic it needs to do, like spell checking every time characters change, or dismissing the keyboard when it receives a return key press.
Delegate methods perform a similar function to callback functions in C.
Hope that makes sense :)
Best and simple concept I got from a Lynda.com Tutorial was: When you set a Delegate it means you have been given work to do. So, if you want to use methods that are written in a protocol method, you must implement them by searching in the Delegate Class Reference and using them. I hope it helped.
By the way, Delegates are excellents. They are your friends. They have been made to make your life as a programmer much easier.
As I understand, Pickers have an Delegate class. Why's there an additional Datasource needed?
There is a difference between a delegate and a datasource.
A datasource is typically used to configure what is displayed by a control. "How many rows do you have?", "What should i display in this row", etc.
A delegate is usually used to let the controlling code know that something happened. "Hey someone selected this row.", "Hey someone started editing this row."
Because the picker view needs information on how to populate the table inside each segment.
Sometimes it may be useful to have one class handling where the data comes from and another handling what to do with it (MVC pattern)
Like most supervisors, the picker is stupid. It can't figure out what to work on, so it keeps being given data and tasks(by the provider); but it needs to have someone who knows what to do with it. That's the delegate.
The API used to combine datasource and delegate methods into one protocol (at least for UITableViews), but it's inflexible - the way it is now you can have a totally different object provide the data to be displayed from the code that is responsible for handling the mechanics of using a picker.
Generally though you do end up wiring both to the same object.