UITableView - using reloadRowsAtIndexPath - ios

I have aUITableView with delegate methods declared. ThenumberOfRows &numberOfSections are updated dynamically.
(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{}
(NSInteger)numberOfSectionsInTableView:
Instead of using the [tableView reloadData], I would need to usereloadRowsAtIndexPath.
However I get a crash with invalid number of rows. How do I handle the dataSource changes? Lets says I have an array of count 10, and when I reload theUITableView usingUIRefreshControls by pulling, and the data from the server. From 10, if the count of array drops to 1, how will I handlereloadRowsAtIndexPath?
[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathForVisibleRows] withRowAnimation:UITableViewRowAnimationNone]
There seems to be a crash when this is called. How would I handle change in data array's count?

To reload specific cells of Tableview the method is reloadRowsAtIndexPaths: not reloadRowsAtIndexPath
[self.tableview reloadRowsAtIndexPaths:[self.tableview indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
However for reloadRowsAtIndexPaths to work properly datasource needs to be consistant. As Indexpaths are already loaded.
If you still use this method, You will get either arrayIndexOutofBound error or duplicate values in cells(depending on increase or decrease in datasource).

//call begin and end updates while performing some hard core actions on tableview
[My_Table beginupdates];
[My_Table reloadRowsAtIndexPaths:[My_Table indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
[My_Table endupdates];
hope it will helps you.

you can try with this.
[tblMe beginUpdates];
[tblMe reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:0 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];
[tblMe endUpdates];
Hope this may help !!!

Related

How to get last cell index path in iOS?

I am building an IOS application where I am using tableView. Now when I reached to last cell I load +10 data from localDB.
After fetching the data I reloaded the tableView that I don't need in place of reload I want to used updated tableView. for that SOF suggested me below code.
[[self tableView] beginUpdates];
[[self tableView] reloadRowsAtIndexPaths:____ withRowAnimation:UITableViewRowAnimationAutomatic];
[[self tableView] endUpdates];
I don't what should be there in reloadRowsAtIndexPaths value. Please can some help me in understanding this above line of code.
You can get the indexPath of the last row in last section like this.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(numberOfRowsInLastSection - 1) inSection:(numberOfSections - 1)];
Here, numberOfSections is the value you return from numberOfSectionsInTableView: method. And, numberOfRowsInLastSection is the value you return from numberOfRowsInSection: method for the last section in the table view.
You don't need to reload cells, because there are no cells after your 10th cell. You want your users to see more cells when they get to the last one as in a news app. The solution is to inset more rows below, here is how:
1- create the rows you want to insert
NSMutableArray *newRows = #[[NSIndexPath indexPathForRow:10 inSection:0]];
3- update your data source array
2- [self.tableView insertRowsAtIndexPaths: newRows, UITableViewRowAnimationAutomatic];

UITableViewRowAnimationNone - behaving as UITableViewRowAnimation(Top/Bottom)

I have set the row insertion with the following code. I am only using UITableViewRowAnimationNone when inserting and deleting the rows, but sometimes ,as you can see in the gif below, the row animates in from the top or bottom. For the most part it doesn't animate, as I want it, but sometimes it animates on insertion and deletion. I am not talking about the table view expanding to show the inserted cell, I mean the cell appears to be sliding in from the bottom or top.
Here is the method that controls the insertion animation:
- (void)contentHeaderFooterView:(NFContentHeaderFooterView *)headerFooterView sectionOpened:(NSInteger)section{
NSIndexPath *pathToAdd = [NSIndexPath indexPathForRow:0 inSection:section];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[pathToAdd] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
And here is the method that controls the deletion animation.
- (void)contentHeaderFooterView:(NFContentHeaderFooterView *)headerFooterView sectionClosed:(NSInteger)section{
NSIndexPath *pathToDelete = [NSIndexPath indexPathForRow:0 inSection:section];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:#[pathToDelete] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
I've had similar issues with table updates not performing the animation I gave it directly. I can't say for sure why, but one thing I can suggest is, instead of doing a specific row deletion between begin/endUpdates, you can just to a hard reloadData.
Answered here: https://stackoverflow.com/a/37352789/577237
Reposted since it's brief:
[UIView performWithoutAnimation:^{
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:rowsToRemove withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}];
Note that this is iOS 7.0+

tableView beginUpdates / endUpdates block reloading entire table even when empty

I have a tableView that periodically gets updated by data coming from a remote service. I load the data, and store the indexPaths of various data that I just inserted, deleted or updated. I then have a begin/endUpdates block that completes the necessary operations, as seen below.
[self.tableView beginUpdates];
if (pathsToDelete) {
[self.tableView deleteRowsAtIndexPaths:pathsToDelete withRowAnimation:UITableViewRowAnimationNone];
}
if (pathsToRefresh) {
[self.tableView reloadRowsAtIndexPaths:pathsToRefresh withRowAnimation:UITableViewRowAnimationNone];
}
[self.tableView insertRowsAtIndexPaths:indexPathsToAdd withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
I noticed recently that cells were being reloaded way more than I was expecting. Following through in the debugger, I noted that in cases where a single record was being refreshed (ie pathsToRefresh was the only one that had anything, and it had only a single index) the entire table was actually reloading. By that, I mean I was seeing requests to the dataSource for each and every cell in the table.
In debugging, I started stripping things down. I got all the way to the point where I only had
[self.tableView beginUpdates];
[self.tableView endUpdates];
And even then, I was seeing the entire table reload (ie cellForRowAtIndexPath was fired for every value in the datasource). So I assumed something else was happening that I'd missed..but removing those two methods resulted in the reload stopping.
Shouldn't begin/endUpdates do nothing in cases where nothing is within the block? I'm at a loss on what is actually happening here, as the doc indicates all they do is bookend table operations - and in this case I have none.
objective c iOS reloadRowsAtIndexPaths , reloadSections
if([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1 == -1){
row = 0;
}else{
row = [self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1 ;
}
NSIndexPath* indexPath = [NSIndexPath indexPathForRow: (row) inSection: ([self.tableView numberOfSections]-1)];
// [self.tableView reloadData];
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
NSLog(#”Number of Sections %ld”, (long)[self.tableView numberOfSections]);
NSLog(#”Number of Rows %ld”, [self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1);

Assertion failure in -[UITableView _endCellAnimationsWithContext:

I'm an amateur at best, and stuck on this error! surely something simple...
- (void)addTapped:(id)sender {
TechToolboxDoc *newDoc = [[TechToolboxDoc alloc] initWithTitle:#"New Item" thumbImage:nil fullImage:nil];
[_itemArray addObject:newDoc];
//[self.tableView beginUpdates];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_itemArray.count-1 inSection:0];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
NSLog(#"%#",indexPath);
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
[self performSegueWithIdentifier:#"MySegue" sender:self];
//[self.tableView endUpdates];
it is breaking on the line the says
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];
You need to add [UITableView beginUpdates] and [UITableView endUpdates] around:
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];
From the class reference:
Note the behavior of this method when it is called in an animation
block defined by the beginUpdates and endUpdates methods. UITableView
defers any insertions of rows or sections until after it has handled
the deletions of rows or sections. This happens regardless of ordering
of the insertion and deletion method calls. This is unlike inserting
or removing an item in a mutable array, where the operation can affect
the array index used for the successive insertion or removal
operation. For more on this subject, see Batch Insertion, Deletion,
and Reloading of Rows and Sections in Table View Programming Guide for
iOS.
I think you are inserting the row in your tableView but not updating the number of rows at section that's why you are getting error in this line. So along with inserting the row You should also increase the array count or whatever you are using to show the number of rows in table view.
In my case, I was using Parse and I deleted a few users (one of which was my iPhone simulator). I got this error whenever refreshing the tableView.
I just deleted the app from the Simulator and made a new account and it works flawlessly.
#droppy's answer helped give me the lightbulb moment of what was wrong!
Hope that helps someone.

ios reload tableview in beginUpdates

I change the height of a cell (when image downloaded) with method like that
-(void)didHeightChanged:(float)imageHeight atIndex:(NSInteger)indexPath
{
[dictionary setObject:imageHeight forKey:indexPath];
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
Everything works well with first data, but when I reload UITableView with second data , probably beginUpdates method doesnt ended and I got issues - when I delete and reload UITableView, cell dont disappear, UITableView shows wrong cells
How can I stop beginUpdates immediately before reload new data?
You should either call [self.tableView reloadData] or [self.tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathWithRow:index inSection:0]]]; // or indexPath if instead of passing a NSInteger you pass a NSIndexPath * to the method.
I found the answer
[self.tableView beginUpdates];
[self.tableView endUpdates];
it was called in background thread...

Resources