Why UITableview scrolling up while reloading data - ios

I have a UITableview with 40 to 50 sections. It is expandable tableview when ever tapped on Section header am expanding that corresponding section if already expanded it will close. My issue is when ever I tapped on Section header requesting server for data and received data from server my Tableview automatically scrolled to top and this is happend after 20th section only. I could not understand whats going wrong.
NSIndexSet *sections = [NSIndexSet indexSetWithIndex:self.selectedIndexPath.section];
[self.tableview reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];

If you do something which changes the height of some of the cells the table will scroll to a different position after the reload.
If you want the tableview to scroll to the top of the tapped section once the load has finished, what about something like:
NSIndexSet *sections = [NSIndexSet indexSetWithIndex:section];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];
NSIndexPath *sectionPath = [NSIndexPath indexPathForRow:NSNotFound inSection:section];
[self.tableView scrollToRowAtIndexPath:sectionPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

Related

Maintain current position of UITableView while calling reloadData with variable height custom cells of UITableView

I have UITableView with variable height custom cells and multiple sections which are not fixed, i am trying to implement load more functionality while user reach at first cell.
After fetching data i am arranging records into NSMutableArray which contains multi-dimensional array to store data section vice.
My problem is when i load more data i don't have idea about how many sections and how many rows in each section comes. So i can not add fix values to move my UITableView at particular position using methods like scrollToRowAtIndexPath or scrollRectToVisible
So every time after getting new record i called reloadData to update my number Of Sections and number Of Rows In Each Section, which also move control to first row of UITableView. I want to be present at current viewing cell not at first cell.
I have also tried answers at reloadData() of UITableView with Dynamic cell heights causes jumpy scrolling this question but that are not helping me.
Don't use reloadData if you want to stay at the same position. Use reloadRowsAtIndexPaths or insertRowsAtIndexPaths or reloadSections instead.
To refresh modified rows with animation:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[indexPathOfYourModifiedCell] withRowAnimation: UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
To add rows with animation (number of rows is automatically increased):
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[indexPathOfYourNewCell] withRowAnimation: UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
Without animation (untested):
[UIView performWithoutAnimation:^{
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[indexPathOfYourNewCell] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}];
Apple documentation: description here

Load more to last position in UITableView

I try to Build UITableView That load every time a 5 object and when I notice that the scroll table in the last position I reload table data and this open the table from the top again.
how I can save the position and when table reload back to last cell I see ?
Use the below code before you reload the table data
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(numberOfRowsInLastSection - 1) inSection:(numberOfSections - 1)];
By the above line you will get the position of last row of table.
Use this code after reloading the tableView
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
This will scroll to already saved position.
I find a solution in this post - UITableView , Scroll to bottom on reload?
[postTableView reloadData];
NSIndexPath* ipath = [NSIndexPath indexPathForRow: oldSkip -1 inSection: 1];
[postTableView scrollToRowAtIndexPath: ipath atScrollPosition: UITableViewScrollPositionTop animated:YES];

UITableView moveRowAtIndexPath displays duplicate cells

I have a UITableView where I move a row from outside the visible scroll area to the top of the UITableView. The animation works as intended but it ends up showing a duplicate cell of what was previously at index 0.
Code looks something like this except for the hardcoded index:
[self.tableView beginUpdates];
[self.tableView moveRowAtIndexPath:[NSIndexPath indexPathForItem:16 inSection:0] toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
[self.tableView endUpdates];
I have this problem on both iOS 8 & iOS 7. Anyone have an idea how to solve this?
The cause of the problem was a bug in the re-ordering of my data provider. I moved a cell in the tableview but the data array did not reflect that change.

Reload data on a UITableView with animation (the table hasn't got sections)

I'm developing an iOS 5.0+ app with latest SDK.
I have a NSArray with 20 elements. I want to show these 20 elements dynamically on a UITableView. I have disabled scroll on the tableview, and I want to remove the first NSArray element every 1 minute, and then reload UITableView to don't show the element that I have removed and show the remanning ones. And I want to do it with animation.
Searching over internet I have found some examples about how to do it using sections, but I have only one section on the UITableView.
In a nutshel,
Load 20 elements into a NSArray.
Show these 20 elements on an UITableView with scroll disabled.
For loop to remove first NSArray element every minute.
After remove, do UITableView reload with animation.
How can I do that?
You don't have to reload the entire table. Just remove the object from your array (once a minute or whatever). The object that you remove will be at index XXX in your array. And then call :
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:XXX inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
Hope this helps. Cheers!
You need to use this :
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:intvalue(your indexPath) inSection:0];
NSArray *array = [NSArray arrayWithObject:indexPath];
[yourtableview deleteRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationFade];

UITableView inserting section at top while scrolling

I am inserting new section (section contains 3 cells) top of UITableView while SCROLLING TOP.
[_mainTable beginUpdates];
[_mainTable insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[_mainTable endUpdates];
Section gets inserting properly. But it takes me top of Table i.e. cell 0 or row 0. I want this transaction to be smooth. I can insert
[_mainTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
after endUpdates but it shows quick jerk because it takes you top of Table then suddenly scroll it to your last position.
How can i make it smooth.
Thanks
I haven't done exhaustive testing on this, but this seems promising:
Identify NSIndexPath of one of the visible cells.
Get its rectForRowAtIndexPath.
Get the current contentOffset of the table, itself.
Add the section, but call reloadData instead of insertSections (which prevents jarring scrolling).
Get the updated rectForRowAtIndexPath that you got in step 2.
Update contentOffset by the difference of the result from step 5 and that of step 2.
Thus:
[self.sections insertObject:newSection atIndex:0]; // this is my model backing my table
NSIndexPath *oldIndexPath = self.tableView.indexPathsForVisibleRows[0]; // 1
CGRect before = [self.tableView rectForRowAtIndexPath:oldIndexPath]; // 2
CGPoint contentOffset = [self.tableView contentOffset]; // 3
[self.tableView reloadData]; // 4
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:oldIndexPath.row inSection:oldIndexPath.section + 1];
CGRect after = [self.tableView rectForRowAtIndexPath:newIndexPath]; // 5
contentOffset.y += (after.origin.y - before.origin.y);
self.tableView.contentOffset = contentOffset; // 6

Resources