UITableview scroll to top on reload goes too high? - ios

I'm using scrollRectToVisible:
[self.tblArticle scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
and/or setContentOffset:
NSIndexPath* top = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
[self.tblArticle scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionTop animated:YES];
and/or this:
[self.tblArticle setContentOffset: CGPointZero animated: YES];
to (try to) scroll to the top of my tableView after reload. But sometimes it goes too high so that I see too much white space above the table. My table has a header that's above the cell rows.
It goes too high when I scroll down a bit and then initiate the reload. If I'm on top, the scrolling is good. But the lower I get before reloading, the more white space is visible above the header.
For now I'm calculating how low I am and then I set something like this:
CGFloat height = 0;
if(self.selectedCategoryID > 2)
height = 250;
[self.tblArticle scrollRectToVisible:CGRectMake(0, height, 1, 1) animated:YES];
which is veeery bad. Thanks for any suggestions!
EDIT I 'm using the uitableview reload like this:
// Reload table
[self.tblArticle reloadData];

try this:
[_mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_mainTableView setContentOffset:CGPointZero animated:YES];
});

Please try this to scroll UITableview to top.
[mainTableView setContentOffset: CGPointZero animated: YES];

Related

UITabelView scrollToRowAtIndexPath scroll to bottom sometimes will made my table disappear, why?

I want my tableview scroll to the bottom when first time into the view, but sometimes won't scroll to the bottom, and sometimes will made my table disappear. (usually happened when first time or second time).
here's my scrolling code:
-(void)tableScrollToBottom{
[self.tableView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection: ([self.tableView numberOfSections]-1)];
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
});
}
and I also have [self tableScrollToBottom] in viewDidAppear, cause if I only scroll the table in viewDidLoad the table always won't scroll to very bottom, and I don't know why, it's really confusing me.
And I tried to put [self.tableView layoutIfNeeded] in [self tableScrollToBottom], and remove the dispatch_async, it seems like the first time I opened the app and into the view still can't scroll to the very bottom, after the first time, it'll scroll to the bottom correctly, I don't know what's the difference between the first time open the app and into that view and after the first time.(my data get from server and it's from previous, and my tableview row height is dynamic).
here's my code in [self tableScrollToBottom] now:
-(void)tableScrollToBottom {
[self.tableView layoutIfNeeded];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection: ([self.tableView numberOfSections]-1)];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
and here's where I called [self tableScrollToBottom] :
-(void)getDicData {
for (int i = 0; i < _csDictArr.count; i ++) {
[_chatPersonArray addObject:_csDictArr[i][#"Person"]];
[_chatDataArray addObject:_csDictArr[i][#"Message"]];
[_chatDateTimeArr addObject:_csDictArr[i][#"Time"]];
}
[self.tableView reloadData];
[self tableScrollToBottom];
}
and I put [self getDicData] in ViewDidLoad, and I also call the tableScrollToBottom in viewDidAppear
-(void)viewDidAppear:(BOOL)animated {
[self tableScrollToBottom];
}
You should use CATransaction to make sure tableView was reload completely before scroll it to bottom.
[CATransaction begin];
[CATransaction setCompletionBlock:^{
CGFloat yOffset = 0;
if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
}
[self.tableView setContentOffset:CGPointMake(0, yOffset) animated:YES];
}];
[self.tableView reloadData];
[CATransaction commit];

UICollectionview custom flow layout delete cell

I have a horizontal UICollectionView that implements UICollectionViewLayout and uses targetContentOffsetForProposedContentOffset for a custom fling/paging functionality. Each cell is nearly the width of the screen with the next cell showing slightly to the right. The functionality works great, but I want to be able to delete the cell at index 0 when the current cell is index 1. I'm currently able to calculate and do this just fine, but upon deleting the index 0 cell it slides to the next cell (old index 2, new 1 (after deleting 0)) because of the current content offset. I'm not sure how I can delete index 0 while maintaining the current layout.
Right now in my delegate I'm doing:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
float cellWidth = self.collectionView.bounds.size.width - 20;
float currentPage = self.collectionView.contentOffset.x / cellWidth;
if (currentPage == 1) {
[self remove:0];
}
}
-(void)remove:(int)i {
[self.collectionView performBatchUpdates:^{
[self.data removeObjectAtIndex:0];
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:0 inSection:0];
[self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
} completion:^(BOOL finished) {
}];
}
So the calculation and deletion works fine, but upon deleting [0], the collection view is scrolled to the next cell..and I'm not sure how to stop it.
I've tried self.collectionview.contentOffset = CGMakePoint(0,0) after the deleting, but the transition is still noticeably buggy. Any ideas on how to approach this problem?
so after a ton of trial and error I was able to resolve the issue. It might be a little hackish but I just wrapped the batch with a uiview animation that has no duration. Basically it overrides the deletion animation
[UIView animateWithDuration:0 animations:^{
[self.collectionView performBatchUpdates:^{
[scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
[self.data removeObjectAtIndex:0];
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:0 inSection:0];
[self.collectionView deleteItemsAtIndexPaths:#[indexPath]];
[self.collectionView.collectionViewLayout invalidateLayout];
} completion:nil];
}];

UITableView beginUpdates endUpdates scrolls to the top of cell

This is what I am doing so as to set the focus on the same point after UITableView beginUpdates :
CGPoint offset = tableMessageDetail.contentOffset;
// CGPoint textPoint = [self.view convertPoint:cell.txtReply.frame.origin toView:nil];
[tableMessageDetail beginUpdates];
[tableMessageDetail endUpdates];
[tableMessageDetail setContentOffset:offset animated:NO];
//[tableMessageDetail scrollRectToVisible:CGRectMake(cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height) animated:YES];
But the position after endUpdates, when the cell is too high, comes to the top of cell. I have tried with the commented approach as well, but that too is not perfect.
Giving a thought, hope this helps:
Remove all animations on the tableView's layer before setting the contentOffset.
[tableView.layer removeAllAnimations];
[tableView setContentOffset:offset animated:NO];
and then,
[tableView scrollToRowAtIndexPath:cell.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

IOS- UITableView scroll back to top

i am using Custom UITableView in my project for displaying data it works fine but when i try to scroll it to bottom it doesn't stop at desired cell it always jumps to the top of the table. only shows 2-3 cells.
please suggest what to add to overcome this problem.
i tried so many codes answered in similar type of questions but they doesn't work
i uses the following codes for UITableView
newsFeedTable = [[UITableView alloc]init];
CGFloat Ytablepadding = CGRectGetMaxY(homeView.frame)+60;
CGFloat heighttable = 700;
newsFeedTable.frame = CGRectMake(0,Ytablepadding, self.view.frame.size.width, heighttable);
[self.view addSubview:newsFeedTable];
newsFeedTable.delegate=self;
newsFeedTable.dataSource= self;
Add this code in you viewDidload :
NSIndexPath *myIndexPath = [NSIndexPath indexPathForRow:AddYourLastIndex inSection:0];
[self.tbl_presentation selectRowAtIndexPath:myIndexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
UITableView is a subclass of UIScrollView, so you can also use:
[newsFeedTable scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
Or
[newsFeedTable setContentOffset:CGPointZero animated:YES];
Simplest you can do is :
calling [newsFeedTable setContentOffset:CGPointMake(0, CGFLOAT_MAX)]
will do what you want.
You need to adjust the table view's height according to the height of the view, of which you are making subview to see the last row of the table or rather to scroll it to bottom:
newsFeedTable.frame = CGRectMake(0,Ytablepadding, self.view.frame.size.width, self.view.frame.size.height - Ytablepadding);
and to scroll it to last row on table reload/ after popping of data, scroll it programatically like this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[newsFeedTable reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
int lastRowNumber = [newsFeedTable numberOfRowsInSection:0] - 1;
NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRowNumber inSection:0];
[newsFeedTable scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
});
});
}];

How to postion tableView to the last inserted section SMOOTH

EDIT:
I found this SO thread.
UITableView inserting section at top while scrolling
I have a tableView
I load it with 5 sections initially
Then I scroll up and when section 0 and row 0 is displayed, I load the next 5 sections and insert in table view using
[self beginUpdates];
[self deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[self insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[self insertSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationNone];
[self insertSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationNone];
[self endUpdates];
However my problem is the tableView gets position at section 0 and row 0 after the inserts
but I want to position at last row of last new section inserted (which is section 2 in code above)
I tried this both inside and outside begin/end updates
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
[self scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionBottom animated:YES];
But it does it abruptly.
After inserting sections you can also scroll the table view to the intended index path using
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
[UIView animateWithDuration: 1.0
animations: ^{
[tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
completion: ^(BOOL finished){
}
];
Note:
1) Insert the above code after [self endUpdates];
2) Please ensure that you keep the animated flag to NO using scrollToRowAtIndexPath: atScrollPosition: animated: while you are using it with UIView's animateWithDuration: animations: completion: API.
3) Also you can calculate the duration based on the distance (content size, height wise for vertical scroll), i.e duration can depend on the distance between source index path and destination index path.
Please try below code.
[self beginUpdates];
/*
Insert your sections
*/
[self endUpdates];
[self performSelector:#selector(scroll) withObject:nil afterDelay:0.1];
-(void)scroll
{
if([Your array count] > 0)
{
[YOURTABLENAME scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:2] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
I Hope above code is work for you.
Thanks

Resources