Reputation: 5240
I've just recently started programming for the iPhone and I'm making an application that connects to a database and gets a set of row names and displays them. When selected, the rows background colour change ie you can make multiple selections and they will all be different colours. So I'm getting the XML back from the server no problem and I have created a UITableView
to display the cells in. However, I have no idea how to add the cells into the table. I had a look at insertRowsAtIndexPaths
but I'm not sure how to use it? As I understand, insertRowsAtIndexPaths
takes two parameters:
An NSArray that contains what row the cell is supposed to be in and in what section. The problem with this is that my app will have a dynamic number of rows. How would I go about creating the NSArray if I don't know how many rows I will have? Can I use NSMutableArray?
The second parameter it takes is an animation - that's pretty straightforward.
Another issue I am having is where do I actually create the cells? How do you pass the cells to the tableview?
I've tried reading the documentation but it just doesn't seem very clear! Here is the code I have at the moment inside the loadview method of the view controller:
//Before this I get the XML from the server so I am ready to populate
//cells and add them to the table view
NSArray *cells = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:0 inSection:0],
[NSIndexPath indexPathForRow:1 inSection:0],
[NSIndexPath indexPathForRow:2 inSection:0],
[NSIndexPath indexPathForRow:3 inSection:0],
[NSIndexPath indexPathForRow:4 inSection:0],
[NSIndexPath indexPathForRow:5 inSection:0],
[NSIndexPath indexPathForRow:6 inSection:0],
[NSIndexPath indexPathForRow:7 inSection:0],
[NSIndexPath indexPathForRow:8 inSection:0],
[NSIndexPath indexPathForRow:9 inSection:0],
[NSIndexPath indexPathForRow:10 inSection:0],
[NSIndexPath indexPathForRow:11 inSection:0],
[NSIndexPath indexPathForRow:12 inSection:0],
nil];
[eventTypesTable beginUpdates];
[eventTypesTable insertRowsAtIndexPaths:cells withRowAnimation:UITableViewRowAnimationNone];
[eventTypesTable endUpdates];
Upvotes: 12
Views: 63430
Reputation: 2988
Don't need to use insertRowsAtIndexPaths
.
Check: UITableViewDataSource Protocol Reference and UITableView Class Reference
The magic happens between this three methods (UITableViewDataSource protocol methods):
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
You just need to fill an array. Yes it can be a NSMutableArray
.
You can fill the array in - (void)viewDidLoad
, for example:
yourItemsArray = [[NSMutableArray alloc] initWithObjects:@"item 01", @"item 02", @"item 03", nil];
And them use the data source methods like this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
// If You have only one(1) section, return 1, otherwise you must handle sections
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [yourItemsArray count];
}
- (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...
cell.textLabel.text = [yourItemsArray objectAtIndex:indexPath.row];
return cell;
}
Like this cells will be created automatically.
If You chage the Array, just need to call:
[self.tableView reloadData];
Upvotes: 16
Reputation: 1113
You need not to worry about it. cells will be created automatically. just look at these UITableview Class Reference
You have to implement UITableView dataSource and delegate Protocol. Also look at this tutorial UITableview Tutorial
Upvotes: 0
Reputation: 3394
//######## Adding new section programmatically to UITableView ############
@interface MyViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
IBOutlet UITableView *tblView;
int noOfSection;
}
-(IBAction)switchStateChanged:(id)sender;
@end
@implementation MyViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad{
[super viewDidLoad];
noOfSection = 2;
}
- (void)viewDidUnload{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
return YES;
}
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - TableView Delegate Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return noOfSection;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.section == 2){
return 200;
}
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
UISwitch *switchBtn = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 20, 10)];
cell.accessoryView = switchBtn;
[switchBtn addTarget:self action:@selector(switchStateChanged:) forControlEvents:UIControlEventValueChanged];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.detailTextLabel.font = [UIFont systemFontOfSize:11];
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.numberOfLines = 2;
}
if(indexPath.section == 0){
cell.textLabel.text = @"Cell-1 Text";
cell.detailTextLabel.text = @"Cell-1 Detail text";
}
else if(indexPath.section == 1){
cell.textLabel.text = @"Cell-2 Text";
}
else { // new added section code is here...
cell.textLabel.text = @"New Added section";
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
-(IBAction)switchStateChanged:(id)sender{
UISwitch *switchState = sender;
if(switchState.isOn == YES){
NSLog(@"ON");
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
[self insertNewSectionWithIndexPath:indexPath];
}
else {
NSLog(@"OFF");
[self removeSectionWithIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]];
}
}
-(void)insertNewSectionWithIndexPath:(NSIndexPath *)indexPath{
noOfSection = 3;
[tblView insertSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
}
-(void)removeSectionWithIndexPath:(NSIndexPath *)indexPath{
noOfSection = 2;
[tblView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
}
@end
Upvotes: 2
Reputation: 3123
I think you're approaching this from the wrong direction. UITableViews don't work as you are expecting. insertRowsAtIndexPaths
is for inserting new rows into a table, rather than for populating it in the first instance.
UITableViews work by calling a number of delegate methods that allow you to present your data to the table view as you need to. The framework then takes care of the heavy lifting to populate cells, handle scrolling and touch events, etc.
I would recommend that you start by reading a tutorial such as this one: http://www.iosdevnotes.com/2011/10/uitableview-tutorial/ , which looks fairly thorough to me. It explains how to set your datasource for the table and how you can configure the way your data is presented by the UITableView.
Good luck!
Upvotes: 18