Im a little bit confused about how to add rows to the table view.
I have an array which gets values added to it regularly. I am trying to update the number of rows everytime a new value is added to the array using these lines of code:
// listOfMembers if a
[[self tableView] beginUpdates]; [tableView numberOfRowsInSection:[listOfMembers count]];
[[self tableView] endUpdates];
[[self tableView] beginUpdates];
[tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
[[self tableView] endUpdates];
however this does not work to change the number of rows.. may i am misunderstanding how the table updates. I get this error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. 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 (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
THe crash is on the line:
[tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
How should I be updating my table view clearly I am doing this in the wrong way.
Ok so the answer to this problem is to simply call the function reloadData. for example:
[tableViewOutlet reloadData];
Related
I am getting error on following line:
[self.tableView deleteRowsAtIndexPaths:#[indexpath]] withRowAnimation:UITableViewRowAnimationFade];
Also the cell at that indexPath is nil since that table cell is not visible on tableview due to tableview scrolled:
TableCell *cell = (TableCell *)[self.tableView cellForRowAtIndexPath:indexPath];
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 5. The number of rows contained in an existing section after the update (25) must be equal to the number of rows contained in that section before the update (28), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Let's say you want to remove item at index 5 in section 0, your code will look like this, In Swift
tblList.beginUpdates()
data.remove(at: 5)
tblList.deleteRows(at: [IndexPath(row: 5, section: 0)], with: .fade)
tblList.endUpdates()
Objective-C code will look like this,
[_tblList beginUpdates];
[data removeObjectAtIndex:5];
[_tblList deleteRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:5 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[_tblList endUpdates];
I am facing a crash issue while inserting a row to tableview.This happens when pagination reload(Very Fast scrolling of tableview) table view and inserting row for ads happens almost similar time.
Ad inserting method
[self.news insertObject:adStory atIndex:index];
NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]];
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[[self tableView] endUpdates];
OperationDidfinish
[_tableView relaoddata];
Crash Logs
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (45) must be equal to the number of rows contained in that section before the update (43), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(0 CoreFoundation 0x000000010e8ebb0b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010e357141 objc_exception_throw + 48
2 CoreFoundation 0x000000010e8efcf2 +[NSException raise:format:arguments:] + 98
3 Foundation 0x00000001088413b6 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
4 UIKit 0x000000010c8d78e8 -[UITableView _endCellAnimationsWithContext:] + 16362
5 UIKit 0x000000010c8ee9cc -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] + 329
Please make sure that number of rows returned in the delegate method - (NSInteger)numberOfRowsInSection:(NSInteger)section;
is equivalent to that of, after you insertRowsAtIndexPaths and endUpdates. E.g if earlier numberOfRows is 4 and you insert one row, than numberOfRows should return 4+1. Else it will be mismatch in endUpdate.
Following crash log describes that only.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (45) must be equal to the number of rows contained in that section before the update (43), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Any UI related changes must be executed on the main thread. Making UI changes on the background thread might result in slowing down the changes.
Try this,
dispatch_async(dispatch_get_main_queue(), ^{
[self.news insertObject:adStory atIndex:index];
NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]];
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[[self tableView] endUpdates];
});
This will take care of moving the changes to main thread if required.
I have a custom tableview cell and am getting data from the network 10 at a time. As users scroll down it fetches 10 more and displays the content.
Sometimes, my fetch can be a bit slow (>3-4 secs) and during that instance(when a fetch is currently happening), if my custom tableview cell is clicked (on the visible rows) then the app crashes at the following line. (I followed the example here to expand/collapse my cell and show more content)
Obviously the tableview:reloadRowsAtIndexPaths is called as and when network fetch is done and making changes to tableview data..so how can i fix this issue ?
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"ROW SELECTED..%ld",indexPath.row);
if (self.selectedIndex ==indexPath.row)
{
self.selectedIndex=-1;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
return;
}
if (self.selectedIndex!=-1){
NSIndexPath *prevPath = [NSIndexPath indexPathForRow:self.selectedIndex inSection:0];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:prevPath] withRowAnimation:UITableViewRowAnimationFade];
}
self.selectedIndex=(int)indexPath.row;
//[self.tableView beginUpdates];
//app crashes at this line !!
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
//[self.tableView endUpdates];
}
The exception i am getting is
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (10) must be equal to the number of rows contained in that section before the update (11), plus or minus the number of rows inserted or deleted from that section (1 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
If self.selectedIndex!=-1 is true, then you are going to ask the tableview to reload twice. I have a few suggestions:
put all those reload calls into dispatch blocks, so you don't issue them directly in a delegate method
aggregate the last two reloads into a single reload by using a mutable array, but again, dispatch to the main queue.
Also, add some logs. What happens if prevPath is out of range - that cell isn't valid any more?
EDIT: your answer is here:
"The number of rows contained in an existing section after the update (10) must be equal to the number of rows contained in that section before the update (11), plus or minus the number of rows inserted or deleted from that section (1 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out)."
Before the update you had 10 items in this section.
After the update you had 11 items in this section
you inserted one and deleted one (this is not shown in your code snippet)
you didn't move any in or out
So you have one more item in your section (told to the tableview in the delegate method) than insertions (net 0) and moves (net 0).
I have a UITableView of custom cells. Each cell has an NSTimer that can be set by the user and started by tapping a button. The timers work except when a new cell is added to the TableView. In the unwind method (coming from creating a new object for a new cell) I have to reload the data in the TableView so that the new cell appears. This however reloads all the cells causing any running timer to restart. Is there a way I can add the cell without restarting the running timers?
EDIT:
I have a ViewController that creates a new object and then back in the FirstViewController.m I have an unwind method that should update the tableView with a row for the new object. Using the reloadData method won't work because it reloads all of the cells. I would like to just add a new cell without reloading the entire tableView.
-(IBAction)unwind:(UIStoryboardSegue *)segue {
ABCAddItemViewController *source = [segue sourceViewController];
ABCItem *item = source.object;
if (item != nil) {
[self.objectArray addObject:item];
[self.tableView reloadData];
}
}
To do this I've tried adding these lines instead of [self.tableView reloadData]:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.objectArray indexOfObject:item] inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
However, the app crashes and I get this message:
'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
The number of rows in the tableView is determined by [self.objectArray count] in the numberOfRowsInSection: method.
It is not a good idea to add timers to cells because they are reused. They are views. My recommendation is to create some objects which have the text / info you want to display in these UITableViewCells and add the timers to those objects. This way the timer info is not stored in the cells and they will store state
There is no need to reload entire table for just inserting one cell. You can add the cell like
self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:row inSection:section]] withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView endUpdates];
When I am reloading one section,after deleting last object from array and reloading section
NSIndexSet *indexSet = [[NSIndexSet alloc]initWithIndex:0];
[_LYTPhotosUICreator.getTableViewInstance reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
then I have an exception
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Please let me know where I did wrong.
Invalid update: invalid number of rows in section 1 this means section 1 current number is 0, before is 4, however, you now do update section 0.
Try this way.
[self.tableView beginUpdates];
// remove the objects from data source
// give the according row indexpaths
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];