UITableView multiple section with multiple dictionaries - iphone

I am trying to work out on this scenario and just curious if it's possible to have multiple sections in one UITableView with with multiple NSDictionary contents? I have been trying to figure this and see if someone have had encountered this issue and how did s/he could get it resolved?
I have segregated count in numberOfRowsInSection method, but at cellForRowAtIndexPath I am having some issues with respect to how to segregate the sections with different dictionaries.

CellForRowAtIndexPath receives the indexPath parameter as an input. The indexPath.section attribute tells you what section of the table the cell is in, and indexPath.row tells you what row within that section. If you have a separate dictionary for each section, then you do a switch on indexPath.section, and get the data from the appropriate dictionary for that row.

If I understand correctly you are using 1 dictionary per section.
Dictionary are unordered, so you must keep in some way the key in a ordered fashion.
You can put your Dictionary in an array in the order you want to show them.
So that's for the section part of your NSIndexPath.
aDictionary = [arrayOfDic objectAtIndex:indexPath.section];
If you want to display the content of that dictionary in ascending order or your key you can do something like that :
anArray = [[aDictionary allKeys] sortedInSomeWayWithSomeSelector];
someObjt = [anArray objectAtIndex:indexPath.row];
Then you have the row for your NSIndexPath.
This is pretty generic, you will have to adapt it to your code.
And I would prefer to cache the orderedKey, because sorting at every row would be a waste of resources, but you got the general idea.

Related

Calling cellForRowAtIndexPath through an instance

I was wondering if the following scenario is possible.
I have a UITableViewController class which contains ten rows displaying some data. Now, I want to show the first five rows in one tableview and the last five in another. Since I don't want to fetch the data again I was hoping to create an instance of my original table class and call its cellForRowAtIndexPath:(NSIndexPath*)indexPath to return the table cells and add it to the other two table views. Is it possible to call a delegate method through an instance? If so, how can I create an NSIndexPath object pointing to a particular row in any section of the table...
Thanks for the replies. I tried calling the cellForRowAtIndexPath:(NSIndexPath*)indexPath but it always shows the following warning
'RootViewController' may not respond to '-cellForRowAtIndexPath:'
Also the application crashes with the message
***Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RootViewController cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x4bad30'
Had initialized NSIndexPath as Andrei described.
Guess its just not possible to call the function.
If you don't want to fetch again, why don't you just add your fetch results to an array?
This would have the advantage that populating your tableview would not require "live fetching" - fetching data as you need it may in some cases make scrolling a tableview slow or stuttering may occur.
However, you could also try to add your tableviewcells to one or more arrays to keep references to them while you pupulate your tableview for the first time.
I don't think you need anything that elaborate.
Have all tables using the same datasource. Choose which items to display in which table based on the tag value for that table element. Call reloadData on all tables when anything changes.
My guess is that using the same UITableViewCell in 2 or more tables would not work.
If you are reusing cells then it's very likely that those duplicated cells will eventually be refreshed with another content.
To protect against this, you would need to clone those cells, in which case it's not feasible to work on a UITableViewCell level.
You're better off storing the data (displayed by the cells) in a array (or other storing way) and share that data across multiple tables.
Plus, you'd have the extra ability to customize the appearance of those tables independently while sharing the same content.
To answer your last question, you can create a NSIndexPath to point to any cell.
The first index is the sectio, and the second index is the row in that section.
For example, to point to section 2, cell 5 you can write something like this:
NSIndexPath* myIndexPath = [[NSIndexPath indexPathWithIndex:2] indexPathByAddingIndex:5];
//Or, with another method:
NSIndexPath* myIndexPath = [NSIndexPath indexPathWithIndexes:indexes_array length:count];
Remember that cellForRowAtIndexPath: is not a method of UITableViewController. It is a method of UITableView. With this in mind you would actually call the method like so:
UITableViewCell *cell;
cell = [yourTableView cellForRowAtIndexPath: indexPath];
Doing so should return the cell at indexPath.

Fetching data from a dictionary inside cellForRowAtIndexPath

I have a set of data inside a dictionary and inside
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
method I want to fetch data from this dictionary. How can we fetch objects for each indexPath.row.
One way, I could think of is getting keys array and then fetch the object from this array based on indexPath.row and then use this key to fetch the dictionary object.
Please suggest.
dictionary is not an ordered collection like array, so the method you've suggested is probably the way to go... Depends on how do you want the data to be presented (sorted by keys/values).
It's not a good practice, because the order of the keys of a dictionary is not defined.
If your data must be a dictionary, then you must provide an explicit information that maps keys of the dictionary and the index path of the table.
For example, you can have another array in which the keys of the dictionary in sorted in the same order by which you would see your objects in the table.
How are your items sorted in the table? Is the order important? There isn't really an easy answer to this question. Are you sure you need to keep a dictionary of your data? The way I see, you have the following options:
call [dictionary allValues] to get an array of all values. You can then sort it the way you want and return the item at index indexPath.row. The draw back is you need to sort the array for each row which is not ideal if you have a lot of items. It might make your scrolling choppy.
keep a copy of a sorted array version of your dictionary and make sure to update it any time your dictionary is updated. This is better suited for a large data set that does not change often. You could wrap both your dictionary and array in a class that will take care of keeping the two in sync.
You'll need to weigh the drawbacks depending on what your data is like.

Dynamic Sections UITableView with Unknown cells

Hey,
I'm basically trying to retrieve data from SQlite db and populate a tableView from it.
The sql-data-retrieval method creates two arrays. "dataArray" and "SectionArray".
DataArray is filled with data NSObjects.
Uptil this point, i can create the appropriate Section headers.
Here is the problem,
-1 What do i do to make sure that the right objects get into their appropriate sections and not under any other sections (which they seem to be doing). Also the Count(number of rows) in each section differs.
What should the code be in "NumberOfRowsAtIndexPath" and cellForRowAtIndexPath methods
-2 What kind of datasource objects are more suited for this type. I'm simply filling up two NSMutableArrays - dataArray(rows) and SectionArray(Section headers).
I think you should make many NSArray one for each table header you have created. In NumberOfRowsAtIndexPath you will return the count of the array for the requested section, and in cellForRowAtIndexPath you will choose your array using the section index (as before) and with the row index you will select the row of that array.

objective-c programmatically change table view from standard to grouped?

The following situation pertains to an iPad app I am working on for my company.
So I have an array of type "Person" that holds the information of a list of people. On the initial page, I have a table that displays their name and picture. When this loads, the results are ungrouped. I was wondering if there was a way to easily group these results with the click of a button based on something like location or business title. The reason they are not grouped when they are loaded is because the powers higher then I deemed it necessary to display the raw list first. Any ideas on doing something like that? Thanks in advance!
You'll want to use "sections" to split the table.
First you need to sort your datasource into the desired groups, and then reflect it in the view.
A dictionary can easily represent the grouped data. Model each group as an array that contains the entries for that group, and then add it to the dictionary with a key that represents the section.
When the data is ungrouped, you can still use the dictionary, but with a single entry, rather than many, and then reflect that in the UI.
That way when you're asked how many sections there are in the table you can return [dictionary count]; and then when you're asked for the number of rows, you can do something like [[dictionary objectForKey#"myKey"] count];
And so on.
When you've reconfigured your datasource you can call [self.tableView reloadData]; to reload the table with the sections.
You'll have to remove the UITableView and add another in it's place via [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];. You can't change an existing style at runtime.
The other way to do it, is have it grouped from the get-go, but return 1 for - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; if it is "ungrouped" and return all rows for - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section when it is grouped, do it the normal way.

NSFetchedResultsController and my TableView structure

I have a tableView controller with two sections. The first section has a couple of input fields and is not really displaying core data. The second section displays items from a database saved with Core Data.
I have an NSFetchedResultsController and I serve up data for cellForRowAtIndexPath and didSelectRowAtIndexPath as follows. For section = 0, I manually serve up the appropriate input fields, and for section = 1 I want to use [fetchedResultsController objectAtIndexPath:indexPath]. () However, since the fetched results controller only knows about one section, this doesn't work.
I know I can create a new IndexPath with section = 0, and then feed that to the NSFetchedResultsController. Is that the preferred solution or is there another way to 'tell' the NSFetchedResultsController what to expect?
The only way to do this is to translate the NSIndexPath objects passed into the various UITableViewDataSource/UITableViewDelegate methods into index paths appropriate for your NSFetchedResultsController. I'd recommend adding a method to your class that does this.
The return values from this method will match the section numbers the NSFetchedResultsController uses. Also, if in the future you end up needing a second header section for whatever reason, it's easy enough to adjust your method to do that.
Why would you need to tell it anything? In the delegate methods, just offset the section index by one and you should be fine.
You can create your own NSIndexPath instance to pass into the NSFetchedResultsController to resolve this issue.
Update
If you want to have two sections then yes that is the right answer. However I would consider putting your input fields into the table header instead of a section. That would be a cleaner answer in my opinion.