How to dynamically add rows / cells to a UITableView by clicking a button on iPhone

Initially, I have a tabular view with one add button.

when the user clicks this button, I need to increase the number of cells and add cells as follows

How to write the number of lines and how to add new lines by clicking the add button

//Number of lines

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return **????** ; } 

// Content on cells / rows

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ?????? } 

// ### Add a new line .. ###

 -(IBAction)myAction:(id)sender { ???????? ; } 

Thanks in advance...

+7
source share
5 answers

In your application, you need to add values ​​to Array when you perform an action in btn.

For example, in your table view, you show NSString in cell.textLABEL.text. These lines are in NSMutableArray.

Now when buttonAction is called

in myAction

 { NSString *newString =@ "NEW CELL"; [tableArray addObject:newString]; [tableView reloadData]; } 

Try this logic in your application regarding your modal.

I hope this logic will be useful to you.

+7
source

UITableView has the ability to insert a row or section. see Apple Doc

There are many textbooks about this. 2 are usually used to add / delete a line / section.

 insertRowsAtIndexPaths:withRowAnimation: deleteRowsAtIndexPaths:withRowAnimation: 

I wrote a similar answer on how to use this: Hiding table cells with on / off switch in iPhone

+11
source

Rebooting the table view every time you want to add or remove a row creates a bad experience for the user of your application. Although this is not an effective way to accomplish this task, it also has some negative side effects - the selected rows do not remain selected after a reboot and the changes are not animated.

UITableView have methods that were created to dynamically change the contents of a table view. It:

 insertRowsAtIndexPaths:withRowAnimation: moveRowAtIndexPath:toIndexPath: deleteRowsAtIndexPaths:withRowAnimation: 

Please note that these methods allow you to specify the type of animation that will be used when performing the specified operation - you cannot achieve this behavior when you use reloadData to change the contents of the table view.

In addition, you can combine several operations with a table view using additional table view methods (this is optional):

beginUpdates endUpdates

It’s just that the transfer operations you want to perform into the calls to beginUpdates and endUpdates and the table view will create one animation for all the operations requested between the calls to beginUpdates and endUpdates so that the whole transition looks better created by several separate animations.

 [self.tableView beginUpdates] //calls to insert/move and delete methods [self.tableView endUpdates] 

It is very important that your data source state matches the one stored in the UITableView . For this reason, you must ensure that when the table view begins to perform the requested operations, its data source will return the correct values.

 [self.tableView beginUpdates] //calls to insert/move and delete methods //operations on our data source so that its //state is consistent with state of the table view [self.tableView endUpdates] 

When does a table view begin to perform operations? It depends on whether the operations in the animation block are defined by the beginUpdates and endUpdates . If so, the table view begins operations after calling the endUpdates method. Otherwise, the table view performs operations immediately after a call to the insert / move or delete method has been made.

When you use the beginUpdates and endUpdates to perform operations on a table view, you need to know that in this case the table view, the package requests the operations and executes them in a certain order, which is not necessarily the same as the order of the calls made by you on your table viewer ( Apple documentation on this ).

The most important thing to remember is that deleting all operations is always performed before all insert operations. In addition, the delete operations are apparently performed in descending order (operations for indices 3, 2, 1), when the insert operation is performed in ascending order (operations for indices 1, 2, 3). Remember that it is important to maintain the state of your data source in accordance with the saved table view.

Spend some time analyzing the order of operations with the data source and the table view presented in the example below.

The final example:

 //initial state of the data source self.numbers = [@[@(0), @(1), @(2), @(3), @(4), @(5), @(6)] mutableCopy]; // //... // NSArray indexPathsToRemove = @[[NSIndexPath indexPathForRow:3 section:0]. [NSIndexPath indexPathForRow:0 section:0]; NSArray indexPathsToAdd = @[[NSIndexPath indexPathForRow:6 section:0], [NSIndexPath indexPathForRow:5 section:0]]; [self.tableView beginUpdates]; [self.numbers removeObjectAtIndex:3]; [self.numbers removeObjectAtIndex:0]; [self.numbers insertObject:@(10) atIndex:4]; [self.numbers insertObject:@(11) atIndex:5]; [self.tableView insertRowsAtIndexPaths:indexPathsToAdd withRowAnimation:UITableViewRowAnimationAutomatic]; [self.tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationAutomatic]; [self.tableView endUpdates]; //final state of the data source ('numbers') - 1, 2, 4, 5, 6, 10, 11 
+7
source

There are other correct answers here (which you should read because they go deeper), but I tried more than a week with this after reading all the solutions that I could find, because there were none (what I found!) With comprehensive examples .

Rules for this: 1. Changes must be made directly to the array containing the elements that you display in the UITableView . If you set some value in UITableViewCell in the tableView:cellForRowAtIndexPath: method to the value in self.expandableArray , then for these methods to work, the changes must also be for self.expandableArray .

  • changes to the array of items displayed in the tableView must be made between [tableView beginUpdates] and [tableView endUpdates]
  • The count of the indexPaths array should equal the count of the extra elements that you add to the tableView (I think this is obvious, but that will not hurt to indicate this)

here is a very simple example that will work on its own.

  @interface MyTableViewController () @property (nonatomic, strong) NSMutableArray *expandableArray; @property (nonatomic, strong) NSMutableArray *indexPaths; @property (nonatomic, strong) UITableView *myTableView; @end @implementation MyTableViewController - (void)viewDidLoad { [self setupArray]; } - (void)setupArray { self.expandableArray = @[@"One", @"Two", @"Three", @"Four", @"Five"].mutableCopy; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.expandableArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //here you should create a cell that displays information from self.expandableArray, and return it } //call this method if your button/cell/whatever is tapped - (void)didTapTriggerToChangeTableView { if (/*some condition occurs that makes you want to expand the tableView*/) { [self expandArray] }else if (/*some other condition occurs that makes you want to retract the tableView*/){ [self retractArray] } } //this example adds 1 item - (void)expandArray { //create an array of indexPaths self.indexPaths = [[NSMutableArray alloc] init]; for (int i = theFirstIndexWhereYouWantToInsertYourAdditionalCells; i < theTotalNumberOfAdditionalCellsToInsert + theFirstIndexWhereYouWantToInsertYourAdditionalCells; i++) { [self.indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; } //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates [self.myTableView beginUpdates]; //HERE IS WHERE YOU NEED TO ALTER self.expandableArray to have the additional/new data values, eg: [self.expandableArray addObject:@"Six"]; [self.myTableView insertRowsAtIndexPaths:self.indexPaths withRowAnimation:(UITableViewRowAnimationFade)]; //or a rowAnimation of your choice [self.myTableView endUpdates]; } //this example removes all but the first 3 items - (void)retractArray { NSRange range; range.location = 3; range.length = self.expandableArray.count - 3; //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates [self.myTableView beginUpdates]; [self.expandableArray removeObjectsInRange:range]; [self.myTableView deleteRowsAtIndexPaths:self.indexPaths withRowAnimation:UITableViewRowAnimationFade]; //or a rowAnimation of your choice [self.myTableView endUpdates]; } @end 

Hope this saves someone a lot of time and headache. If you do this like this, you do not need to reload the entire tableView to update it, and you can choose an animation for it. Free code, do not knock it.

+2
source

You can simply add the object to the array and reload the table view with the click of a button.

 [array addobject:@""]; [tableview reloaddata]; 
0
source

All Articles