iOS - UITableView not scrolling to bottom - ios

I am building a chat app in iOS but I have some problems with the UITableView displaying all the messages. I want the table view to be scrolled to the bottom on load so users can see the latest messages when they open the app.
To do this I added this code in my function refreshing the data:
NSIndexPath* ipath = [NSIndexPath indexPathForRow: [self.messageOnTimeline numberOfRowsInSection:0]-1 inSection: 0];
[self.messageOnTimeline scrollToRowAtIndexPath: ipath atScrollPosition: UITableViewScrollPositionTop animated: YES];
This worked fine until I added a header to the tableview. I added the following code and now it doesn't scroll to the bottom when I load the app:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
return view;
}
Does anyone knows why?
Many thanks for your help

Add this code in you viewDidload :
Swift 5
let indexPath = IndexPath(item: <Row Index>, section: <Section Index>)
tableView.reloadRows(at: [indexPath], with: .automatic)
Objective C
NSIndexPath *myIndexPath = [NSIndexPath indexPathForRow:AddYourLastIndex inSection:0];
[self.tbl_presentation selectRowAtIndexPath:myIndexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];

try this code.it will scroll to bottom of tableview
[self.tableview setContentOffset:CGPointMake(0, self.tableview.contentSize.height-self.tableview.frame.size.height) animated:YES];

#Darshan Kunjadiya answer is right.
Even we can achieve the same in storyboard.
Select tableView --> from the storyboard control click on 'add Missing constraints'. That will add the constraint to tableView and View.
That helped me to resolve this issue. A screen_shot attached for reference.
screen_shot Link

Related

Why does insertRowsAtIndexPaths always cause the TableView to scroll to the top?

I've been banging my head on this problem for hours, but every time I try something like this:
self.dataArray.append(newCellObj)
and then I do this:
self.tableView.beginUpdates()
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
self.tableView.endUpdates()
The UITableView will automatically scroll to the top of the page.
Even if I try:
self.tableView.scrollEnabled = false
self.tableView.beginUpdates()
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
self.tableView.endUpdates()
The UITableView will still scroll to the top even with scrolling completely disabled. What exactly causes the ScrollView to scroll to the top after insertRowsAtIndexPaths is called?
The only solution I have for this issue is to use this:
self.tableView.reloadData()
instead. If I use reloadData instead than it's fine, but then I lose the nice animation which I'd really like to keep.
I also have self.tableView.scrollsToTop = false and I've tried many other configurations like that that could disable scrolling somehow, but, there's something that overrides this after insertRowsAtIndexPaths
I was encountering the same issue as OP. Additionaly, sometimes some of my table view cells would go "blank" and disappear altogether, which led me to this related question.
For me, the solution was to do ONE of the following:
implement func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
disable auto layout
set a more accurate estimatedRowHeight on my UITableView
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
// I'm use auto layout and this variant without animation works
// ...insert object to datasource
NSUInteger idx = [datasource indexOfObject:myNewObject];
if ( NSNotFound != idx )
{
NSIndexPath *path = [NSIndexPath indexPathForRow:idx inSection:0];
[self.table beginUpdates];
[self.table insertRowsAtIndexPaths:#[path]
withRowAnimation:UITableViewRowAnimationNone];
[self.table endUpdates];
[self.table scrollToRowAtIndexPath:path
atScrollPosition:UITableViewScrollPositionBottom
animated:NO];
}

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 doesn't scroll to bottom

I have a UITableView where I add rows dynamically. Basically a chat app.
I need to scroll the UITableView to bottom after reloadData
My code is:
It scrolls to here:
https://dl-web.dropbox.com/get/Screen%20Shot%202014-12-05%20at%2013.04.23.png?_subject_uid=44249794&w=AADgJkJJOGK_ANH_cXWnxeXmhFmF5KHjZllg-kP66HARdw
When manually scrolling, I can scroll even further to here: https://dl-web.dropbox.com/get/Screen%20Shot%202014-12-05%20at%2013.05.19.png?_subject_uid=44249794&w=AADtQEfMHMy0Ounri5W3gBTLNgR4uckT_gBdYQel9vD1qQ
My code:
[_chatTable reloadData];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow: [[AppData getChatLog]count]-1 inSection: 0];
[_chatTable scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
I need the UITableView to scroll all the way to the bottom.
Sorry,I couldn't open up the given links.Try this
UITableView *yourTableView = yourTableViewToBeSetHere;
CGRect lastCellRect = CGRectMake(0, CGFLOAT_MAX, 50, 50);
// Scroll to the particular rect
[yourTableView scrollRectToVisible:lastCellRect
animated:YES];
Good luck!

How to scroll to the top of a UITableView in iOS 7

In iOS 7, I use the following code to scroll to the top of my UITableView. You have to account for the overlap of the translucent status bar and navigation bar.
[tableView
setContentOffset:CGPointMake(
0.0,
-tableViewController.topLayoutGuide.length
)
animated:YES
];
This works only works after the first time you call it. On the first time you call it, my table gets scrolled much farther than it should, showing a lot of white space. Additionally, the UIRefreshControl appears frozen. You have to nudge the table a little to make it bounce back to the true top. Afterwards, you can call this code as many times as you want and it behaves as you'd expect it.
I've tried other ways, but they all have problems. The iOS 6 way behaves just as oddly on the first call. Although it doesn't jump a huge amount on subsequent calls, they are not correct because it scrolls to 64.0 points below the top of the table because we forgot to account for the status and navigation bar.
[table setContentOffset:CGPointZero animated:YES];
I've also tried scrolling to the first cell, but it doesn't scroll to the very top in one call. It will only scroll up one page's worth every time you call it.
[tableView
scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:YES
];
Try this one:
NSIndexPath* top = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
[tableView scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionTop animated:YES];
In SWIFT
let top = NSIndexPath(forRow: NSNotFound , inSection: 0)
tableView.scrollToRowAtIndexPath(top, atScrollPosition: .Bottom, animated: true)
Swift 4.0 and above
let top = NSIndexPath(row: NSNotFound, section: 0)
tableView.scrollToRow(at: top as IndexPath, at: .bottom, animated: true)
i looked at other answers and found the following solution that worked for me.
-(void) scrollToTop
{
if ([self numberOfSectionsInTableView:self.tableView] > 0)
{
NSIndexPath* top = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
[self.tableView scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
}
Hope, it solves your problem.
it's not "magic". The 64 offset is for status bar(20 points) and navigation bar(44 points) heights. If the scrollview have offset of 0 and you also have status bar + navigation bar, it would be under these objects and you will see -64.0 of your original content. In storyboard there is an option "Adjust scroll view insets" and this is checked by default
Try:
[tableView
setContentOffset:CGPointMake(
tableView.contentOffset.x,
-tableView.contentInset.top
)
animated:YES
];
Please try this:
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
The sample is like this:
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:0 animated:YES];
In Objective-C
[mainTableView setContentOffset:CGPointZero animated:YES];
And in Swift:
mainTableView.setContentOffset(CGPointZero, animated:true)
In Objective C
NSIndexPath* top = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
[self.tableView scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionTop animated:YES];
In Swift
var scrollIndexPath: NSIndexPath = NSIndexPath(forRow:NSNotFound , inSection: 0)
self.tableview.scrollToRowAtIndexPath(scrollIndexPath, atScrollPosition: UITableViewScrollPosition.top, animated: true)
iOS scrollview is behaving a bit oddly. The 64.0 offset was added "magically" to the first scrollview in the view hierarchy "the first time" as you mentioned. I haven't figured out why this was happening. At the moment I only had a really hackish solution: you can add a dummy scroll as the first scrolling in the view hierarchy, with height set as 0. After that, you solution should work as usual.![enter image description here][1]
screenshot : http://imgur.com/LvrbcqG
Hope this helps.
Anyone else know why this is happening in the first place ?

Is that possible to use UIPageControl to control the move of UITableView?

From Apple sample "PageControl" we can know that UIPageControl can be used to control movement of pages in scrollview.
As UITableView is subclass of UIScrollView,I want to use UIPageControl to control the movement of table view cell just like in "PageControl".
But can not find any interface of delegate for me to do that.
Question is :
Is that possible to do this ? And Why ?
Thanks
Let me answer my question with :
Programmatically Selecting and Scrolling
Listing 6-5 Programmatically selecting a row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath {
NSIndexPath *scrollIndexPath;
if (newIndexPath.row + 20 < [timeZoneNames count]) {
scrollIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row+20 inSection:newIndexPath.section];
} else {
scrollIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row-20 inSection:newIndexPath.section];
}
[theTableView selectRowAtIndexPath:scrollIndexPath animated:YES
scrollPosition:UITableViewScrollPositionMiddle];
}
It sure is possible, but why would you want this? A table view scrolls vertically, while a page control has a horizontal layout, so it would probably look/feel weird.
Anyway, if you really want to do this, add your view controller as a target of the page control:
[pageControl addTarget:self action:#selector(pageChanged:) forControlEvents:UIControlEventValueChanged];
Then implement the scrolling in the action:
- (void)pageChanged:(UIPageControl *)sender {
float scrollPosition = ((float)sender.currentPage / (float)sender.numberOfPages) * tableView.contentSize.height;
[tableView scrollRectToVisible:CGRectMake(0, scrollPosition, 1, 1) animated:YES];
}

Resources