Best way to re-use a UITableView with dynamic data? - iphone

My application has a series of table views based on some hierarchical data. For example, the user selects "Browse by XYZ" on my CategoryListController, and then I load my DocumentListController based on that selection.
Right now I'm getting the list through a web service that returns some JSON data, but that's beside the point. I could retrieve this dynamic list from a SQLite database, and I would have the same underlying challenge.
The problem here is that since the list of items for my table view in DocumentListController will change depending on which selection the user tapped on, I have to load my list after the table view is displayed.
Right now I'm using -viewWillAppear: to trigger this "refresh" of the data items from my web service. I was wondering if this is the best way to be doing this refresh, or if I should look into using a different method. I tried using -viewDidLoad but that method gets called only once for the DocumentListController, and I have to check at every invocation if the "selection" has changed, and if so, I need to call my web service again.
What's the best way to do something like this?

Since you retrieve the data through the network, I would suggest to post a notification after you process it. Your DocumentListController should register for that notification and invoke its table view's reloadData in the notification handler.
Another approach, if the data will always be there when displaying the view, is what you've suggested - update table view in viewWillAppear.

Related

retain entries in UITableView

I have the following (view) controller arrangement:
an uitableview --(embedded in)--> navigation controller --(embedded in)--> Tab bar controller --(modal segue to)--> button in a view (uiviewcontroller).
description of my problem:
The view with the button is the initial view of my app. Pressing this button leads to a tableview in a tab bar. At the beginning the table view is empty, but you can manually add information on the cells, like names. However, once you go back to initial view (with button) and press the button again, the previous entries in the table view are erased.Can somebody give a hint how to retain these entries with the given arrangement. Thank you very much in advance.
You can use the singleton pattern. It will create a shared instance of your object, that you can access anywhere. You will then be able to write in it when the user adds a row in the table, and read it when you come to the tableView.
Here is a bit of help : Singleton pattern
EDIT : you can also use core data, but it may not be appropriate in your situation (plenty of docs on the web about that one)
This is quite a question as it really isn't about the interface per se. It is more to do with general Object Orientated Programming and the life time of objects.
Basically your data needs to be stored higher up the object hierarchy. It needs to persist across construction/destruction of the interface objects. This could also be done by storing the data in persist-able data store such as a DB or file but you would still need to store the means to extract the data or subset of data from the store.
If you wish to persist the data you could store data in a singleton data class and reference it statically or store it in your UIApplication object and pass that down the hierarchy as you create each object. you would probably have to subclass each object and add a new constructor passing in a ref to the data.

Preload classes upon app launch

I have an app where on the main view that is initially loaded, it will have an indicator that will show how many items are in a tableview that is in another class. I presume I have to preload the tableview class while the app is launching so the indicator can update correctly, how can I do this?
What is the table's datasource? I'd say if the data in the table is coming from a plist or other file, you could load the file into an array in the main view's class, be able to get a count from that, and then just reference it from this class when you need it in the tableview class. But if the datasource is coming from information generated mainly inside the tableview class, then I'd think you'd have to load it all first.
A table view's job is just to be the view that represents some data model. That data model is usually an array of some kind that represents items in database, a plist, somewhere online, etc.
You shouldn't be thinking about invisibly preloading the actual table view here-- that's overkill and breaks the MVC design-- the count of the items is a function of that underlying data model, so just preload the data model (or do whatever you need to do to load the item count).
There are multiple ways to pass around or share a reference to that underlying data model once its loaded, so you can use it from both views, but you'll have to say more about the structure of your app (and probably ask another question) to get good advice on that.

How to use a tableView as a selector to send values to another viewcontroller?

I'll try to explain this as best as i can, but i appologize if it gets too confusing - I've been stuck on this problem for many hours now.
In my application i have a search screen where the user will be able to select a bunch of criterias to perform the search by. Some of these criterias consists of fairly long lists of values to choose from and therefor i want a tableview on my searchscreen which have 4 rows - Each row representing a criteria that the user can set.
Once the user clicks on a row i want to push a new window in my navigationcontroller which consists of a new table containing the selectable values for that criteria - Once the user clicks on one of these rows on the new window, i want the selected value to be sent back to my main searchscreen and pop back to my search screen.
What would be the best way to do this?
Elaboration:
My searchscreen is called SearchViewController and is contained in a navigationController.
SearchViewController contains two sliders and a tableView with 4 rows called "Searchtype", "Property type", "Salestype", "Area" and a searchbutton. If the user clicks on "Searchtype" then i want a new view to be pushed in the navigationController which should contain a new tableView with a bunch of rows representing different possible values for the "Searchtype" criteria - The same goes for all 4 rows in SearchViewController.
When the user clicks on one of the value rows in the newly pushed tableView i want that tableView to be popped away and the selected value sent back to the SearchViewController allowing the user to either select more criterias or push the search button to actually perform a search based on the selected criterias.
But i can't figure out the best way to do this?
I really appreciate any help i can get - I'm going nuts trying to figure this out :)
Btw. i don't use Interface Builder - All UI elements are coded manually.
5 ways to do it here:
1) Let the Search View Controller be the delegate of action in the Search Type View Controller, so that when the user selects a search type, it will be informed. Use protocol for proper check at compile time if you want, and remember to use assign instead of retain for the delegate, to avoid circular reference.
2) Set the UINavigationController delegate to Search View Controller (or whatever class you want to control it), and listen to the event when the Search Type View Controller is popped out.
3) Implement a "refresh" function in viewWillAppear: as suggested above, but this is not recommended, because the implementation of viewWillAppear: sucks and not reliable at all. Maybe good for simple app, but when the structure of your app gets complicated, forget it.
4) Use NSNotificationCenter. Your Search View Controller will observe all changes to search criteria, and in each child view controller, when the user changes it, post a notification. This is more complicated, but much more powerful and flexible than all the methods above.
5) Similarly, you can use Core Data to store all search criteria in an object, and listen to changes in that object using KVO. This is a bit more advanced and may be overkill, but if you know KVO, it makes life much easier in Objective C, so probably worth taking a look anyway.
Btw: It's good to do all the UI by hand coding to understand the concepts at first, but try to move to Interface Builder whenever you can. It is a much recommended way to work (there are countless threads on this in Stackoverflow or on the web, with more elaborated discussions on why IB is better).

iPhone programming guideline : List / detail / modify

I have a program that displays a list (a TableView).
When the user clicks an item, it's detail is shown.
On the detail view, the user can ask to modify it so a modify window is shown.
Here, the user can ask to delete the item.
I would like at this time return to the list with the item deleted from the list and from the data source.
There may be thousands of methods to do this, but I wonder which is the best / good one.
Could you help me, and/or give me a good reference to read about this ?
I think he ask how to get from view number 3 back to first view.
Then you can put your three views inside a UINavigationController and call on the last view popToRootViewControllerAnimated:
at least Two options:
Delegation - Create a protocol called something like: TableDetailModifierDelegat
and add methods like modifierDidChangedItem:(id)item
or modifierDidDeleteItem:(id)item
and to the modifying view controller add instance variable id so when you done editing or deleting you will call the appropriate methods.
of course you will need to make your table view controller implement the protocol you created. if you modified or deleted an item you should update your data source and reload the data to the table.
also pass the Table View Controller as the delegate when creating the Modifying View Controller.
Passing The Data Model.
This is much more simple to implement.
you can simply pass your data model to the modifying view controller, and make the changes directly to the data model.
You should keep the data model as Instance Variable in the modifying view controller.
when you done, dont forget to reload the data to your table.
In this instance, you could simply remove the data from the data source the UITableView is using and then call the reloadData method on the table. (As you're editing the data in question, you'll presumably have a suitable method/reference by which to delete it.)
As a bit of reading, I'd recommend Apple's Table View Programming Guide for iOS - this provides a lot of useful background information.

How can I get a method to call in a class while the user is in a view of another class?

I have an iPhone app based on a tabBar and tableViews. I want the user to be able to click on one tab and access options for filtering the data in the initial tableView.
The problem I'm having is that while the user is selecting filter criteria, I want the main table (not visible) to update. The reason this is important is that I want to show how many cells are still in the table as it is being filtered in the navigation bar.
Currently, the method for filtering the main table (-handleFilter) is called in the viewWillAppear method of my rootViewController class. How can I call this method from my "searchOptions" class?
Thanks for the help!
It sounds like you're conflating too much between your model and your controllers (assuming you're following the MVC design pattern). The other controllers besides the main table should be able to query the model themselves to display the count information without asking the main table controller.
I could be misunderstanding something though, a little more information on what data you're using and how it's being filtered in the controllers attached to the other tab bar items would help.
The most straightforward way would be to give the options controller a pointer to the list controller. Then you can call the method directly.
Other options include defining a method/property on some global object (like your app delegate) to access the list controller from elsewhere in the app, and using a more decentralized mechanism like NSNotificationCenter to pass that information around (rather an a method call), or relying on the model itself to notify all of the controllers accessing it when it changes (possibly using Key-Value Observing, or an explicit delegate protocol).