i've a UITableView and I'm reading a data from a web service.
the data from the web service may change at any time, so i have to refresh my data periodically.
i've managed to refresh the data and store it in an NSArray, but the UITableView won't display those data.
i tried
[myTableView reloadData];
but it have no effect.
EDIT:
i've implemented all the methods to load the data from an NSArray to the UiTableView.
this works when the NSArray is initialized in the ViewDidLoad.
but if the NSArray changed while the application is running, the UITableView Will not display those changes.
You need to implement the UITableViewDataSource delegate protocol, specifically - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Use this method to set up the cell. You can use the row property of indexPath to determine which cell you are setting up and provide it with data from your array.
For example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
id item = [dataArray objectAtIndex:indexPath.row]; // Whatever data you're storing in your array
cell.textLabel.text = [item description]; // Substitute this for whatever you want to do with your cell.
}
EDIT:
reloadData should call
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView and
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
to see if there are any cells to be drawn. Make sure you implement these methods as well and return non-zero values or your table view won't try to draw any cells and - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath won't be called.
Parse
You may also be interested in this library which claims to make remote data-driven tables a lot simpler.
You have to call the function where you put the content into the table.
Related
If I have UITableView as a property of a UIViewController and I'm manually accessing a cell at a particular row with [tableView cellForRowAtIndexPath:indexPath].
On one method invoke, should I expect to see multiple calls to:
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Each of my UITableViewCell has a UITextField whose text data I'm trying to access.
Here's what I'm doing:
for (int section = 0; ix < countOfSections; ++section)
{
NSInteger countOfRowsInSection = // attained
for (int row = 0; row < countOfRowsInSection; ++row)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
// the follow call seems to elicit multiple invocations
// on my table delegate's
// - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [self.tableview cellForRowAtIndexPath:indexPath];
// Access some custom data
}
}
Is there a better way to access all of the data stored in the UITextField each of the UITableViewCell for all sections & rows?
You really shouldn't be trying to use views for data storage. In whatever you're using as the table's data source there should be an array (or other structure) of objects that contains the data that provides content for the cells when tableView:cellForRowAtIndexPath: is called.
If you need other access to that information, you should be getting it directly from the data structure rather than the display.
I've been trying to fill a UITableView with data from a NSMutableArray. I have a View-Based application project and so far I've tried every tutorial I found but so far, it just doesn't work. I linked the dataSource and delegate to the File's Owner, I added the procotols UITableViewDelegate and UITableViewDataSource to my UIViewController, I create an array containing 3 strings just to try and debug, everytime I load the app, the table stays empty.
I'm not sure what could be my error, or where I should look to find the problem, if you guys got any idea that would be nice.
Thank you
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection: (NSInteger)section
{
return [yourArray count];
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [yourArray objectAtIndex:row];
return cell;
}
That should populate the table from an array. I've used it several times in my app.
I guess you did forget to call -reloadData on the table view.
Make sure the dataSource and delegate are properly connected to the view controller, also make sure your UITableView is property connected with the outlet if you are using storyboards or a xib file.
If nothing works I recommend you to use XLData that makes UITableView data loading much more simple to implement.
I've searched around and I can't seem to figure out how to do this. It doesn't help that I don't really know what I am totally doing yet, but I hope this will help.
I am creating an iPad application. In short it is a complex stopwatch that will take splits (for running) on one view.
I have a master clock, and 5 buttons for separate splits. All that works. But, I want to record these splits and I thought it would be great to do it in a table that can be scrolled through.
I have 5 UITableViews on the one view. I found some stuff online for a "datasource protocol" and got everything working great for just one table. Things went to crap when I tried to make it work separately for each table. Also, it seemed like a ton of code for a simple task.
I have 5 mutable arrays already present. I really don't know how to go about this and any help would be great!
Also, if possible, i need to clear the tables with the press of a button...seems simple, but I truly don't know.
Thanks!
You need to set UITableViewDelegate and UITableViewDataSource for all your tables to a class that will implement the following methods:
For UITableViewDataSource:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
As these methods are passed the calling tableview, it should be easy for you to return the correct data for the tableview in question (which you are already storing in an NSMutableArray). You still need to cater for displaying different content for your arrays, but I trust you will manage to do so. NSIndexPath basically tells you which part of your array should be displayed. Assuming, for now, that you are working in an ungrouped table, you would simple create a new cell and fill it with the contents of your array, which is determined by the indexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyNiceIdentifier";
cell = [aTableView dequeueReusableCellWithIdentifier:NavigationCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.tag = 500;
}
cell.textLabel = [myArray objectAtIndex:indexPath.row];
}
In the other data source method, you simple return the count for that array:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(tableView == myFirstTableView) {
return [myFirstArray count];
}
}
The method of UITableViewDelegate you will likely use most often is this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
which you use to return the desired height for a cell at a given indexPath.
Setting dataSource and delegate is as simply as doing:
myTableView.delegate = ...
myTableView.dataSource = ...
See this documentation:http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITableViewDelegate
Please also refer to this documentation:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html
I have 25 table cells and I want to load all of them together, without reusing them.
Any Idea?
If you want to avoid recycling table cells, you can just avoid calling dequeueReusableCellWithIdentifier: in your tableView:cellForRowAtIndexPath: method.
If you want to do a one-time initial load of all your cells, you can do something like this in the init method of your table's data source:
// myCellArray is an instance var of type NSMutableArray.
myCellArray = [NSMutableArray new];
for (int i = 0; i < 25; ++i) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
UITableViewCell *cell = [self tableView:tV cellForRowAtIndexPath:indexPath];
[myCellArray addObject:cell];
}
This will keep the cells in memory, since they'd be retained by myCellArray for you.
To be more efficient, your cellForRowAtIndexPath: method can be something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([myCellArray count] > indexPath.row) {
return [myCellArray objectAtIndex:indexPath.row];
}
return [self createCellAtRow:indexPath.row];
}
However, you want to be careful about using more memory than you think is needed, and avoid taking too much time initializing your table. In many cases, your app is likely to appear faster and use less memory if you just use recycled cells in the standard way (as suggested, for example, in the UITableViewDataSource docs).
You can't load them all together. But for "not-reusable" cells, you can make unique cell-reusable-identifiers. So, it system needs the same (first, second, third) cell — it can get already created one. And for new cells they will be created as needed.
And if you reeeeeally need to load all the cells at once, you can call
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
in viewDidLoad for every indexPath you needed.
I need help in using checkbox cell. I currently added the object to tableview. It looks ok until i tried building and running the program where I cannot check the checkbox. I am currently using a tableview which displays items runtime with a checkbox for each item so i can have multiple selections.
I am new to xcode and I have been stuck for a week with this problem. i tried google but still no luck.
Any snippets, answers, or explanations is very much appreciated.
First we need to edit this method: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath. Assuming you generated a Navigation-based application, this method should already be there, only commented out. I don't know the exact details of your implementation, but you somehow have to keep track of the checkbox state for each cell in the tableView. For example, if you had a BOOL array, the following code would work:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (checkboxArray[indexPath.row])
checkboxArray[indexPath.row] = NO;
else
checkboxArray[indexPath.row] = YES;
[self.tableView reloadData];
}
Now that we know what cells need to have a checkmark next to them, the next step is to modify how the cell is displayed. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath handles the drawing of each cell. Building off the previous example, this is how you would display the checkbox:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if (checkboxArray[indexPath.row]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
cell.accessoryType = UITableViewCellAccessoryNone;
// Configure the cell.
return cell;
}
If we don't call reloadData, the checkmark will not show up until it goes off-screen and reappears. You need to explicitly set the accessoryType each time because of the way cells are reused. If you set the style only when a cell is checked, other cells that may not necessarily be checked will have a checkmark when you go to scroll. Hopefully this gives you a general idea on how to use checkmarks.