Adding Data/Rows to UITableView (Multiple Tables on one view) - iphone

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

Related

How to dynamically update your UITableView when a button is pressed?

I'm stuck with a seemingly very simple app that I'm trying to develop
Basically, I have a UITable, and two buttons: red/blue
When a button is pressed, a row with corresponding title of that button is append to the table
I'm overwhelmed by how complicated UITableView has to be implemented (datasource, delegate, resuable identifier, etc)
Can anyone help me out with this, preferably show me detailed codes
For my Buttons, I have something like this
- (IBAction)buttonPressed:(UIButton *)sender{
NSString *item = sender.currentTitle;
[self.cellArray addObject:item];
[self.myTable reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.cellArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"The Table Cell";
self.myTableCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (self.myTableCell == nil) {
self.myTableCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
self.myTableCell.textLabel.text = [self.cellArray objectAtIndex:indexPath.row];
return self.myTableCell;
}
Since you are learning this..i will post a simple solution.
Make add a member variable NSMutableArray *cellArrays;
initialize it in your viewDidLoad
in buttonPressed check;
if([#"red" isEqualToString:[YourButton titleForState:UIControlStateNormal]])
{
[self.cellArrays addObject:#"red"];
}
else
{
[self.cellArrays addObject:#"blue"];
}
[self.YOURTABLEVIEW reloadData];
Now in your table view datasource method
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.cellArrays.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//in between your code;
YOURCELL.textlabel.text = [self.cellArrays objectAtIndex : indexpath.row];
}
Try this ..
I'd recommend subclassing UITableViewController, then override the dataSource and delegate methods and you should be good to go. Going straight to UITableView is more complicated without any obvious benefits.
You may not be using Core Data, but I still recommend this lecture because it hooks up a TableViewController and works great - all code included. Check it out:
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/node/289
The lectures in iTunes U explain everything further.
Enjoy,
Damien
I wanted to add that "One more thing, the compiler shows a warning says no reusable identifier. what exactly is that?" above...
His answer is correct, but to get rid of that compiler warning...
The tableviewcell of your tableview has to have an identifier. In IOS 5, in your storyboard, highlight the TableViewCell in your TableView, and enter a value in the Identifier. This must match the value in your code of the cell that you are creating.

Refreshing UItableView Data from a frequently changing NSArray

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.

UITableview strange behaviour

I have a UITableView with a top navigation bar. The data for the UITableView comes from an array which contains more than 20 objects.
Everything is fine so far. However sometimes when i do repeated scrolling (fast), I find last row being repeated, sometimes gets cut into half, overwritten.
I am new to iPhone development and have no clue why this happens.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [appDelegate.preList count];
}
// Customize the appearance of table view cells.
- (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];
}
// Configure the cell...
Item *i=[appDelegate.preList objectAtIndex:indexPath.row];
cell.textLabel.text=i.iName;
cell.accessoryType=UITableViewCellAccessoryNone;
return cell;
}
I have attached a screenshot of my problem as well. Notice how the navigation bar and the last cell are.
Help would be greatly appreciated
This looks like you have added two identical table views to your view. If you place a break point on numberOfSections… and then inspect the tableView object, I bet you will find two different table views. Start by looking for places in your code where you [self.view addSubview:tableView] or something similar. Remember, if you are using IB to setup your table, you do not need to programmatically add it.
I think you are seeing this when scrolling fast because only then the tableView bounces leaving some content offset. You have probably added 2 tableViews back to back.

UITableViewCell - Load 25 cells - don't reuse

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.

Checkbox cell in a table view: User can't check it

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.