I have a tableView with with some sections and each section with some rows.Every row has a favorite button.If the button is clicked the row should get added to the favourites section.
(which is initially empty).
I have written some code.but the problem is it is working in iOS 5 simulator and getting crashed in iOS 6 simulator with Invalid tableView update error.
Can someone tell me where the problem is.?
-(void)moveRowToFavourites:(id)sender{
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:[NSIndexPath indexPathForRow:favouritesArray.count inSection:0]];
[favouritesArray insertObject:cell.textLabel.text atIndex:favouritesArray.count];
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:(NSArray *)tempArray withRowAnimation:UITableViewRowAnimationFade];
[[self tableView] endUpdates];
}
EDIT
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(searching){
return [self.searchResults count];
}
else{
if ([[arrayForBool objectAtIndex:section] boolValue]) {
if(section == 0){
return favouritesArray.count;
}else{
NSString* key = [self.proCategoriesArray objectAtIndex:section - 1];
NSArray *aArray = [sectionContentDict valueForKey:key];
return aArray.count;
}
}
return 1;
}
}
You just should call the following:
[favouritesArray addObject:cell.textLabel.text];
[tableView reloadData];
Make sure you implemented this function:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch(section){
case 0:
return favouritesArray.count;
//Your other sections have to placed here, too
default:
return 0;
}
}
Then your tableView should update itself. The problem is that you insert whole cells, but you just have to insert data in your array. Hope it helps!
It seems like your data source is returning 0 as number of sections and rows. You are not correctly inserting/deleting rows, when you insert a new row, data source methods get called again, and if for instance you try to insert an object in a way that the row count will be 4, and data source tableView:numberOfRowsInSection: returns 3, you get an exception because you're trying yo add more objects that what data source promises.
When you try to update a table view all these data source methods get called again:
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView;
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath;
You must ensure that they return correct values. I suspect that you aren't even implementing them.
Edit
The problem is that you are just inserting a new object in favouritesArray, but this doesn't affect the number of rows returned by tableView:numberOfRowsInSection:. There you aren't returning favouritesArray.count, the exception is due to the fact that tableView:numberOfRowsInSection: returns a lower number than the rows that the table view should have.
In your case I think that you don't even need to call insertRowsAtIndexPaths:, you can do everything with your data source:
-(void)moveRowToFavourites:(id)sender {
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
[favouritesArray insertObject:cell.textLabel.text atIndex:favouritesArray.count];
[[self tableView]reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return favouritesArray.count;
}
In tableView:cellForRowAtIndexPath: you should return a cell that has an object fetched form favouritesArray as text.
Related
Using some API, I am displaying data in table view format.
A) In that when API is called first time we will get 10 user details, so at first time we can see 10 rows in tableview. When we scroll down i.e after 10 rows, a new API called for nextPageURL i.e page 2 and it contains gain 10 user details. Again when you reach 20 row after again nextPageURL i.e page 3 API will call and again 10 records will get in JSON and again it will displayed in tableview. (This is working fine. There is no issue while getting data and displaying in data) This is the working flow my tableview in my project.
B) Here I am using UILongPressGestureRecognizer for selecting rows of tableview. Using UILongPressGestureRecognizer I can able to select multiple rows. (This is also working fine)
C) Code used for it, selecting and deselecting tableview row
#interface InboxViewController ()
{
NSMutableArray *selectedArray;
NSString *selectedIDs;
}
#property (strong,nonatomic) NSIndexPath *selectedPath;
- (void)viewDidLoad
{
selectedArray = [[NSMutableArray alloc] init];
self.tableView.allowsMultipleSelectionDuringEditing = true;
UILongPressGestureRecognizer *lpGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(EditTableView:)];
[lpGesture setMinimumPressDuration:1];
[self.tableView addGestureRecognizer:lpGesture];
[self reload]; // for getting data
}
-(void)reload
{
// API sample
NSString * url= [NSString stringWithFormat:#"%#api/v2/get-userDetails?token=%#&api=%#&show=%#&departments=%#",[userDefaults objectForKey:#"baseURL"],[userDefaults objectForKey:#"token"],apiValue,showInbox,Alldeparatments];
NSLog(#"URL is : %#",url);
// here get JSON (First 10 user details data)
}
-(void)EditTableView:(UIGestureRecognizer*)gesture{
[self.tableView setEditing:YES animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.currentPage == self.totalPages
|| self.totalTickets == _mutableArray.count) {
return _mutableArray.count;
}
return _mutableArray.count + 1;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [_mutableArray count] - 1 ) {
NSLog(#"nextURL111 %#",_nextPageUrl);
if (( ![_nextPageUrl isEqual:[NSNull null]] ) && ( [_nextPageUrl length] != 0 )) {
[self loadMore]; // this method is called for getting next data i.e getting next 10 user details
}
else{
NSLog (#"ALL Caught UP");
}
}
this is for first API call and here I will get 10 user details and I am displaying in tableview.
For getting next user details following method is called
-(void)loadMore
{
// next page API called here
}
for selecting row I am using following,
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 3;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
Selecting and deselecting rows
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
self.selectedPath = indexPath;
if ([tableView isEditing]) {
// [selectedArray addObject:[_mutableArray objectAtIndex:indexPath.row]];
[selectedArray addObject:[[_mutableArray objectAtIndex:indexPath.row] valueForKey:#"id"]];
count1=(int)[selectedArray count];
NSLog(#"Selected count is :%i",count1);
NSLog(#"Slected Array Id : %#",selectedArray);
selectedIDs = [selectedArray componentsJoinedByString:#","];
NSLog(#"Slected Ticket Id are : %#",selectedIDs);
}else{
// goes to next detail view
}
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedPath = indexPath;
// [selectedArray removeObject:[_mutableArray objectAtIndex:indexPath.row]];
[selectedArray removeObject:[[_mutableArray objectAtIndex:indexPath.row] valueForKey:#"id"]];
count1=(int)[selectedArray count];
NSLog(#"Selected count is :%i",count1);
NSLog(#"Slected Id : %#",selectedArray);
selectedIDs = [selectedArray componentsJoinedByString:#","];
NSLog(#"Slected Ticket Id are : %#",selectedIDs);
if (!selectedArray.count) {
[self.tableView setEditing:NO animated:YES];
}
}
My Problem/Issue -
I am selecting row of tableview using UILongPressGestureRecognizer, up to 10 rows (it is in front end) and in background in one array its id is storing. If you select some rows, its row id will add in selectedArray if you deselect row it will remove object from selectedArray
Now suppose I selected 5 tickets and suppose when I scroll down (after 10 rows) new API will call, and next 10 userdetails will display, but this time whatever selected rows are vanishing (selected rows are showing unselected) but still in background there id is stored.
What I want is that, when I select some rows even I scroll down and goes to any page, that selected arrow will not vanish and that that selected row is stored in selectedArray object
If you're using multiple selection, you can add this method to your ViewController and call it whenever you need to call [tableView reloadData] to preserve the selection.
- (void)reloadTableView
{
NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
[self.tableView reloadData];
for (NSIndexPath *path in indexPaths) {
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
Referred from save selected row in UITableView after reloadData
I have a UITableView having many rows that contains UITextFields. User enters data to these fields. user can delete or add any rows. When i am trying to delete any row it deletes the correct row from the array(that contains all the cell's reference) but the UITextfield always shows that the last row is deleted.
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _countEmailValues.count ;
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CustomEmailCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[LACustomEmailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.emailTextField.tag = 555;
cell.deleteEmailFieldButton.tag = indexPath.row;
NSLog(#"delete email Field tag %i",cell.deleteEmailFieldButton.tag );
cell.emailTextField.delegate = self;
if ([_countEmailValues count] > 1 )
{
cell.deleteEmailFieldButton.hidden = false;
}
else
{
cell.deleteEmailFieldButton.hidden = true;
}
// Reason why I am adding cell.emailtextfield in this delegate? is should be in addButtonclick but cell.emailtextfield is not
// initialized there. Also adding of only cell will give null for the emailTextField.
// So adding all cells here and then removing duplicates entires and accessing over the app.
[_emailValues addObject:cell.emailTextField];
// Remove Duplicate elements.
NSArray *emailFieldCollection = [_emailValues copy];
NSInteger index = [emailFieldCollection count ] -1;
for (id object in [emailFieldCollection reverseObjectEnumerator])
{
if ([_emailValues indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound)
{
[_emailValues removeObjectAtIndex:index];
}
index--;
}
NSLog(#"Row : %i",indexPath.row);
return cell;
}
- (IBAction)deleteEmailClick:(UIButton *)sender
{
NSIndexPath *index = self.emailTableView.indexPathForSelectedRow;
// [self.emailTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0] animated:YES scrollPosition:0];
NSIndexPath *indexPath = [_emailTableView indexPathForSelectedRow];
NSLog(#"Tags %i", sender.tag);
// [self.emailTableView reloadData];
if ([_countEmailValues count] > 0)
{
[ _countEmailValues removeObjectAtIndex:sender.tag];
}
// NSLog(#"array after %#",_countEmailValues);
if ([_countEmailValues count] == 0)
{
// _deleteEmailButton.hidden = true;
_doneButton.hidden = true;
}
NSLog(#"array before %#",_emailValues);
if ([_emailValues count] > 0)
{
[_emailValues removeObjectAtIndex:sender.tag];
}
[self.emailTableView reloadData];
}
The _emailValues gets updated properly but the data in the fields is always getting cleared of the last one.
EX: in the image if i delete "b" the _emailValues gets cleared properly but the ui shows two field having data "a" & "b" . what have i missed here?
pls help.
You are not deleting the cell . In deleteEmailClick add this line
[self.emailTableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
Also I would like to point out another way of implementing delete using a block. This will ensure that you always have the correct cell and no need to tag your delete button. This would be cleaner and maintainable. In your custom cell class LACustomEmailCell declare a block property like so
#property (strong, nonatomic) void (^deleteButtonTappedBlock)();
Connect the IBAction of your delete button in the LACustomEmailCell class and from there call this block. I am assuming the name as deleteButtonPressed
- (IBAction)deleteButtonPressed:(id)sender {
self.deleteButtonTappedBlock();
}
Now in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can set the block like this
[cell setDeleteButtonTappedBlock:^(){
//Action to perform when cell is deleted. In your case the code in `deleteEmailClick` will go here.
//In the end delete the cell.
[self.emailTableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
i hope this helps
I have a one View controller managing 2 tableviews. I use a flag to track which table is selected. In each of the delegate functions I just check the flag and use the right table.
Everything works great except that when i load the second table which has lesser items than the first one, crashes when I scroll the table , for the following error.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 2 in section at index 0'
* First throw call stack:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Drawing Row = %d Total num Of items = %d", indexPath.row, [[self.fetchedResultsControllerComments fetchedObjects] count]);
Prints this:
Drawing Row = 2 Total num Of items = 0
If the number of items in this table is correct, then why is this function getting called in the first place?
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(currentSelectionTableType1)
{
// Draw first kind of cell.
PlainImageCell *cell1 = [tableView dequeueReusableCellWithIdentifier:#"ImageCell"];
if(cell1 == nil)
cell1 =[[PlainImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"ImageCell"];
[self configureCell1:cell1 atIndexPath:indexPath];
return cell1;
}
// else Draw the second kind of cell
PlainTextCell *cell2 = [tableView dequeueReusableCellWithIdentifier:#"TextCell"];
if(cell2 == nil)
cell2 =[[PlainTextCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TextCell"];
[self configureCell2:cell2 atIndexPath:indexPath];
return cell2;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(currentSelectionTableType1)
return [[self.fetchedResultsControllerDataSource1 sections] count];
return [[self.fetchedResultsControllerDataSource2 sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo;
if(currentSelectionTableType1)
{
sectionInfo = [self.fetchedResultsControllerDataSource1 sections][section];
}
else
{
sectionInfo = [self.fetchedResultsControllerDatasource2 sections][section];
}
return [sectionInfo numberOfObjects];
}
Thx
EDIT - based on the code you added:
You need to define one cell before your conditional and then configure that cell based on the conditional and then return the cell after the conditional. If you need both an ImageView and a TextCell, you can configure those objects in the conditional code.
Why not just use one TableView with two datasources and switch out the datasources as needed?
Something like this:
#property(nonatomic, strong) NSArray *tableViewDataSource1;
#property(nonatomic, strong) NSArray * tableViewDataSource2;
#property(nonatomic) BOOL usingDataSource2;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.usingDataSource2) {
return [self.tableViewDataSource2 count];
}
return [self. tableViewDataSource1 count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create the cell before conditional
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier" forIndexPath:indexPath];
// Conditionally configure the cell
if (self.usingDataSource2) {
// Configure Cell using self.tableViewDataSource2 data
} else {
// Configure Cell using self.tableViewDataSource1 data
}
// Return the configured cell after the conditional
return cell;
}
I'm trying to get a UITableView to work with Core Data using an NSFetchedResultsController, while also having an insertion control (UITableViewCellStyleInsert) as the last row during editing.
Since the insertion control is just another tableviewcell, just with a different editing style, I have changed the appropriate UITableViewDatasource delegate methods, like:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self isInsertionControl:indexPath]) {
return UITableViewCellEditingStyleInsert;
} else {
return UITableViewCellEditingStyleDelete;
}
}
The reported number of rows should also be updated accordingly, when editing (assuming there's only one section for now):
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id<NSFetchedResultsSectionInfo> sectionInfo = self.fetchedResultsController.sections[section];
NSUInteger numberOfObjects = sectionInfo.numberOfObjects;
// FIXME, things will go out of hand with more than one section.
if (self.tableView.editing) {
return numberOfObjects + 1;
} else {
return numberOfObjects;
}
}
And if requested, return the appropriate cell for the insertion row:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableViewCell = nil;
if ([self isInsertionControl:indexPath]) {
static NSString *InsertIdentifier = #"InsertCell";
tableViewCell = [tableView dequeueReusableCellWithIdentifier:InsertIdentifier
forIndexPath:indexPath];
} else {
tableViewCell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier
forIndexPath:indexPath];
[self configureCell:tableViewCell atIndexPath:indexPath];
}
return tableViewCell;
}
This doesn't work, can anybody help me find out why?
QUICK EDIT
To be clear, I have 2 prototype cells in my storyboard, one for the regular content and one for representing the insertion row, both with the appropriate reuse identifier.
I've dug through and found several examples of dynamically adding rows to a UITableView just not to a grouped table and I just can't figure this out. I know what I want to do - I have a grouped table with 3 sections. I want to dynamically add an 'Add new item' row/cell to sections 1 and 2 but not 0 when the edit button is selected.
First I'm confused about numberOfRowsInSection. I'm initially loading my table with this.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[tableData objectAtIndex:section] objectForKey:#"Rows"] count];
}
Do I need to add an if statement for when I'm editing to add a row to the count for those sections when I'm editing? such as:
if (editing) {
return [[[tableData objectAtIndex:section] objectForKey:#"Rows"] count] + 1;
}
And I realize that the above, if correct, would add a row to each section not just 1 and 2. How would I limit that?
Next is my setEditing function. This is where my real problem is. I believe I need to make an array of index paths of the last rows of sections 1 and 2 so that I can insert the new rows below them. The below is wrong, just my experimentation trying to get something inserted somewhere.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:1];
NSMutableArray* paths = [[NSMutableArray alloc] initWithObjects:indexPath, nil];
NSArray *paths = [NSArray arrayWithObject:
[NSIndexPath indexPathForRow:6 inSection:1]];
if (editing) {
[[self tableView] insertRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationTop]; }
else {
[[self tableView] deleteRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationTop]; }
}
That crappy code returns this error:
Invalid update: invalid number of rows
in section 1. The number of rows
contained in an existing section after
the update (5) must be equal to the
number of rows contained in that
section before the update (5), plus or
minus the number of rows inserted or
deleted from that section (1 inserted,
0 deleted).
So I'm a bit lost. IndexPaths and Arrays are new to me. Actually it's all new to me and I do pour over the docs and posts here but I can't say I always understand it. Any help would be appreciated. I also do realize that I still need to configure my cell and commitEditingStyle methods but I think I can figure that out if I can get a handle on understanding index paths and arrays.
thanks
-----EDIT-----
Ok, so I got this for the most part. I've added a new row to my sections when editing:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(self.editing && section != 0) {
int rows = 0;
rows = [[[tableData objectAtIndex:section] objectForKey:#"Rows"] count] + 1;
return rows;
}
else {
int rows = 0;
rows = [[[tableData objectAtIndex:section] objectForKey:#"Rows"] count];
return rows;
}
}
I've figured out how to apply a label to those new rows when in editing mode:
- (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...
if(self.editing && indexPath.section != 0 && (indexPath.row == [[[tableData objectAtIndex:indexPath.section] objectForKey:#"Rows"] count])) {
cell.textLabel.text = #"Add new Item";
return cell;
}
else
cell.textLabel.text = [[[tableData objectAtIndex:indexPath.section] objectForKey:#"Rows"] objectAtIndex:indexPath.row];
return cell;
And I'm properly setting the last row of my two sections where the row was added to style insert:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0)
//Can't edit the items in the first section
return UITableViewCellEditingStyleNone;
else
//if it's the last row in sections 1 or 2 make it an Insert item
if(self.editing && indexPath.section != 0 && (indexPath.row == [[[tableData objectAtIndex:indexPath.section] objectForKey:#"Rows"] count])) {
return UITableViewCellEditingStyleInsert;
}
//Everything else in sections 1 or 2 should be Delete style
else
return UITableViewCellEditingStyleDelete;
}
That all works. Of course it doesn't animate and I still need help with that. I think, but I'm not certain that I need to do the insert/delete rows from the setEditing method. What I believe I need to do is make an array to the sections that I'm editing and then insert the rows there. The *paths array below is wrong because I need an array that points to the last rows in sections 1 & 2 and I don't know how to create that array. Or maybe everything I'm thinking is just wrong. Can someone help point the way? Much thanks.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
NSArray *paths = [NSArray arrayWithObject:
[NSIndexPath indexPathForRow:?? inSection:??]];
if (editing) {
[[self tableView] insertRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationTop]; }
else {
[[self tableView] deleteRowsAtIndexPaths:paths
withRowAnimation:UITableViewRowAnimationTop]; }
}
Do I need to add an if statement for when I'm editing to add a row to the count for those sections when I'm editing?
Yes, in your tableView:numberOfRowsInSection: method, you should return count + 1 in the editing mode. If you do not want to add a row to section 0 then adjust your if condition, i.e.
if( self.editing && section != 0)
Your second problem is related to the first one. You are inserting a new row to the section 1 but
numberOfRowsInSection still returns 5 for that section. It should return 6.
The methods insertRowsAtIndexPaths:withRowAnimation: and deleteRowsAtIndexPaths:withRowAnimation:
are just to reload the table efficiently and with animation. I suggest you to implementsetEditing:animated function as below for now. Then you should implement your tableView:numberOfRowsInSection: and tableView:cellForRowAtIndexPath: methods by taking editing state into account. After everything is working properly, you can use insert and delete methods to have more control over which parts of the table are reloaded.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
[self.tableView reloadData];
}
--EDIT--
You are in the correct path. You can get the indexPaths to delete/insert with a code similar to below:
NSArray *paths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:[[[tableData objectAtIndex:1] objectForKey:#"Rows"] count] inSection:1],
[NSIndexPath indexPathForRow:[[[tableData objectAtIndex:2] objectForKey:#"Rows"] count] inSection:2],
nil
];