rebuild table cells in UITableViewController - iphone

I have a UITableViewController that when loaded gets data from a web-service and stores it locally in an NSMutableArray, once that is loaded I need to loop through that data to build my table cells.
I have all of the code for looping through my array working fine I just need to know how to fire my controller to rebuild the table so my it displays my data.

[self.tableView reloadData];

After saving the datas in mutatable array after calling webservices, call tableview reloadData
[self.tableView reloadData];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [datas count];
}
Make sure that you update the mutable array "datas" value after storing content in mutable array, such as datas will have the web service contents.
Here is sample program of parsing and displaying the parsed content in table, you can refer it how they are reloading their table after parsing
All the best.

I ended up following the instructions here for creating a UITableViewDataSource class, works like a champ!
UITableViewDataSource simplified

Related

cellForRowAtIndexPath Usage Pattern

In the below code I want to perform some DB actions when a cell is deleted, therefore I need to send my Server information about the cell being deleted. If I remember correctly cellForRowAtIndexPath should never be called directly, However I cannot think of any other way to get cell info in the below method, so my question is:
Is it acceptable to call cellForRowAtIndexPath manually below:
[tableView cellForRowAtIndexPath:indexPath]);
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[localGlobalNotifications removeObjectAtIndex:indexPath.row];
[notificationTableView beginUpdates];
[notificationTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[self postLeaveRequest];
NSLog(#"Row is : %#", [tableView cellForRowAtIndexPath:indexPath]);
[notificationTableView endUpdates];
}
}
To clarify: I understand that I can invoke a delegate call of cellForRowAtIndexPath by calling reloadData, what I'm trying to do is access the cell being deleted within commitEditingStyle. I'm not trying to reload my tableView, instead I want to get a reference to the cell being deleted. - Is it acceptable to obtain a reference to said cell by calling cellForRowAtIndexPath directly?
There's nothing wrong with asking the TableView to give you the cell, just as you do in your sample code.
Here's the documentation for the return value:
An object representing a cell of the table or nil if the cell is not visible or indexPath is out of range.
If you're annotating the cell with 'model' data then I think you're breaking the MVC pattern. Your view doesn't need to know about the model data in this way, and so querying the view to make a database change will make life difficult you in the future (readability, extensibility and reusability for example)
You would be better off having your DB metadata stored in a collection such as an NSArray - or an NSArray of NSArrays.
Then you could get all the data you need with something like:
id modelData = myModel[indexPath.section][indexPath.row];
Yes you can use cellForRowAtIndexPath: as they have also used in apple docs or you can create an array of your cells then you can delete it from there and reflect it in your database.
You can call cellForRowAtIndexPath: method using following line, here it will automatically calls all delegate and datasource methods.
[tableView reloadData];
or
[tableViewObjct reloadData];
Hope this solves your problem!

Populating UITableView with Dictionary Data

My Situation:
I have an NSDictionary object. Keyed by NSNumber. Values are custom objects.
I want to put dictionary values into a UITableView. As far as I can tell, UITableView requires that its source collection be indexed so when cellForRowAtIndexPath is called, you can use the indexPath to look up the value.
Problem is that when didSelectRowAtIndexPath is called, I want to look up the object from the dictionary, but I don't have the key. All I have is the indexPath.row.
My solution:
I create an array of keys. I use the index of the array to get the key, and then use the key to get the object out of the dictionary.
My problem:
This seems kind of sloppy especially since this is a routine task (populating the UITableView and then responding when someone touches a cell). Is this the way it's designed to work or is there a better way?
The problem is that dictionaries don't have an order, while a table view does. The answers to this question should give you some ideas for alternative ways of handling this.
As mentioned in another answer, an NSDictionary's keys are not ordered, therefore you are not guaranteed to get the rows in a particular order. That said, it is quite easy to use a dictionary for use with a UITableView.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// tableview cell setup
NSArray* keys = [self.data allKeys];
cell.textLabel.text = [self.data objectForKey:[keys objectAtIndex:indexPath.row]];
return cell;
}
If you need the list to be ordered according to how you entered them into the NSDictionary, Matt Gallagher from Cocoa With Love offers an elegant solution with his take on OrderedDictionary. You can read about it here.

(iphone) how to refer multiple tableview

Hi I have a view that contains 2 tableviews.
For a single view I know this delegate method can help me fill content of each row
(void) tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
But since I have 2 tableviews, how can I refer to each of them and fill content separately?
Thanks for helping!
The "current" tableview will pass a pointer to itself along as an argument when calling its delegate's methods like the one you mentioned.
So, all you need to do is to compare the pointer (tableView) to references of the two tableviews that you stored or added as property previously.
Proceed like so within your delegate methods:
if (tableView == myFirstTableView) {
//code to handle first tableview
} else if (tableView == mySecondTableView) {
//code to handle second tableview
}
Edit: Both tableviews need to share the same delegate for this to work, which would make sense anyway since they appear on the same view.
since you have two table view so you need implement proper if else condition where you need which table view is going to display.Ok
Make IBOutlet for both table.
then now in viewWillAppear
make datasource for the display(Array of data)
and
if(...)
{
firstTable.hidden=NO;
secondTable.hiden=YES;
[firstTable reloadData];
}
else
{
secondTable.hidden=NO;
firstTable.hidden=YES;
[[secondTable reloadData];
}
Now dont worry with every condition you would not require any condition in CellForRowAtIndexPath or didSelectRowAtIndexPath.
Further to Toastor's answer above, you may of course set different delegates and data sources for each table, although most often it is simpler to use the same delegate/data source for all NSTableViews in the same view.
I prefer to use property tag for distinguishing the desired UIView. The UITableView is a subclass of UIView, so it have this property too.

UITableView and NXXMLParser ... Calling Hierarchy

I am stuck in a strange situation , i am getting data from the website using XML files and i am filling an Array (NSMutableArray Type) that i later use to display the data on Table View. The problem is that functions related to UITableView are called earlier and at that time the Array is not filled, this cause the program to crash. When this function is executed arrayData is empty and count functions returns nothing. Is there any way that i call NSXMLParser functions earlier than the UITableView functions.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayData count];
}
Thanks,
Taimur
The array would return 0 if it existed but without containing any objects - so the app shouldn't crash. This means your array has not been initialized yet. You have propably added a pointer to your array as an instance variable and maybe as property, but you still need to create the actual object towards which that pointer should point.
So, if we're dealing with a property of a viewcontroller subclass here, add something like this to your viewDidLoad method:
NSMutableArray *newArray = [[NSMutableArray alloc] init];
self.arrayData = newArray;
[newArray release];
Your situation is not strange at all - it is extremely common when developing apps with asynchronous data loading requirements.
NSXMLParser is a SAX (event-driven) parser - it will parse data when the data is available. It is up to you when you choose to display your table, but obviously if you try to display it before the XML data is available then you will have to take steps to prevent a crash, or at the very least a bad user experience. Typically you would display an activity spinner or a "loading data..." message until the data is ready, and in a background thread load the XML. Once loaded, the BG thread should signal to the UI thread that the data is ready, and perhaps invoke reloadData on the table to load the data.

numberOfRowsInSection did not return mutable array length

I am new to iphone development. numberOfRowsInSection method of UITableViewController executed before parsing the XML node so that this method return value as zero, but this method should be return value of number of rows with data.
please help me
thanks.
After parsing of your XML data is finished call [myTable reloadData]; - it will force your UITableView to reload the data shown and thus all necessary methods (including numberOfRowsInSection) to get called.
I've had a similar problem before, and it was because I was passing the array/dictionary to the controller from the appdelegate. Unfortunately, after the app delegate went out of scope, the array was lost.
Try doing an array copy,
NSArray data = [NSArray arrayWithArray: passedInArray];
Sorry, don't have my trusty macbook on me to check the code, but you get the drift.
I solved this problem via made connection between tableView reference and file owner in interface builder.