Adding a row to iOS TableView

I am very new to iOS development, and I have a terrible time trying something that should be easy; to add an extra row to the TableView each time the user clicks on one of the existing rows. There is no real purpose in this action, I just want to understand the behavior of TableView.

So, I did the following:

I used a template based on Split View and changed the number of rows to 30 in the RootViewController.

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return 30; } 

The tableView: didSelectRowAtIndexPath method looks like this:

 - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* When a row is selected, set the detail view controller detail item to the item associated with the selected row. */ NSMutableArray* paths = [[NSMutableArray alloc] init]; NSIndexPath *indice = [NSIndexPath indexPathForRow:30 inSection:0]; [paths addObject:indice]; detailViewController.detailItem = [NSString stringWithFormat:@"Second Story Element %d with all its information and bla bla bla", indexPath.row]; [[self tableView] beginUpdates]; [self.tableView insertRowsAtIndexPaths:(NSArray *) paths withRowAnimation:UITableViewRowAnimationNone]; [[self tableView] endUpdates]; } 

When I run the program and click on one of the elements, I get the following error:

*** The application terminated due to the unannounced exception "NSInternalInconsistencyException", reason: "Invalid update: invalid number of lines in section 0. The number of lines contained in the existing section after the update (30) must be equal to the number of lines contained in this section before updating (30), plus or minus the number of rows inserted or deleted from this section (1 inserted, 0 deleted).

I have not changed any other part of the code that the template provides.

I read Apple’s documentation and answers to the following questions in some detail: Add a row dynamically to the TableView iphone and also how to use insertRowsAtIndexPaths correctly?

The second question seems to concern the same problem, but I am not able to understand what is happening. What do they mean with dataSource? The answer, which I understand better, says the following:

This is a two-step process: First, update your data source so that numberOfRowsInSection and cellForRowAtIndexPath return the correct values ​​for your data after insertion. You must do this before inserting or deleting rows, or you will see the "invalid row count" error you get.

What does this data source update imply?

Sample code would be highly appreciated because I'm completely upset.

By the way, everything I try has nothing to do with entering edit mode, right?

+8
ios tableview
source share
4 answers

You need to keep the synchronized counter tableView:numberOfRowsInSection:

So, when you have 30 rows, and then say that tableview inserts a new row, you need to make sure tableView:numberOfRowsInSection: will now return 31.

 - (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { return self.rowCount; } - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.rowCount++; [self.tableView beginUpdates]; [self.tableView insertRowsAtIndexPaths:(NSArray *) paths withRowAnimation:UITableViewRowAnimationNone]; [self.tableView endUpdates]; } 

In practice, you probably use an array to track strings return [self.rows count]; etc.

+14
source share

The answer is pretty simple. If you want to change the presentation of the table, you need to follow two simple steps:

  • Deal with a model
  • Transaction with table animation

You have already completed the second step. But you missed the first one. Usually, when you are dealing with a table, you pass it a data source. In other words, some data to display inside it.

A simple example is the use of NSMutableArray (it is dynamic, as the name implies) containing dummy data.

For example, create a property similar to the following in .h

 @property (nonatomic, strong) NSMutableArray* myDataSource; 

and in .m synthesize it as:

 @synthesize myDataSource; 

Now you can alloc-init install this array and populate it as follows (for example, in the viewDidLoad method of your controller).

 self.myDataSource = [[NSMutableArray alloc] init]; [self.myDataSource addObject:@"First"]; [self.myDataSource addObject:@"Second"]; 

Then instead of hard coding the number of displayed lines (30 in your case) you can do the following:

 - (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { return [self.myDataSource count]; } 

Now in you didSelectRowAtIndexPath delegate you can add a third element.

 - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self.myDataSource addObject:@"Third"]; [[self tableView] beginUpdates]; [self.tableView insertRowsAtIndexPaths:(NSArray *) paths withRowAnimation:UITableViewRowAnimationNone]; [[self tableView] endUpdates]; } 
+3
source share

It seems like one big problem with tableView:numberOfRowsInSection: You must return the correct number of rows in this method.

For this it is usually better to support NSArray or NSMutableArray elements to represent the table, so in this function you can say: return [arrayOfValues count]; . Store the array as a property of the view controller class so that it is easily accessible in all methods.

The array can also be used in cellForRowAtIndexPath: If you have an NSString array, you can say cell.text = [arrayOfValues objectAtRow:indexPath.row]; .

Then, when you want to add an element to the table view, you can simply add it to the array and reload the table, for example. [tableView reloadData]; .

Try to implement this concept and let me know how this happens.

+2
source share

You can also do this for a daily table cell.

  -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [arrayStationStore count]; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIndentyfire; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentyfire]; if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentyfire]; } cell.textLabel.text = [arrayStationStore objectAtIndex:indexPath.row]; return cell; } -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Check if current row is selected BOOL isSelected = NO; if([tblStationName cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark) { isSelected = YES; } if(isSelected) { [tblStationName cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; [arrayReplace removeObject:indexPath]; NSLog(@"array replace remove is %@ ",arrayReplace); } else { [tblStationName cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; [arrayReplace addObject:indexPath]; NSLog(@"array replace add is %@ ",arrayReplace); } return indexPath; } 
0
source share

All Articles