简体   繁体   中英

How to scroll a UITableView to the tableFooterView

I have a UITableView whose contents are dynamically changing, like a FIFO stack. Cells are added to the bottom and removed from the top.

This works beautifully, and I can scroll to the indexPath so that the newest message always scrolls down to the bottom (Like a chat application).

Now.. I want to add a footer to that table section. Instead of using

SrollToRowAtIndexPath

I would like to be able to scroll to the tableFooterView.

Any ideas how I can do that would be appreciated.

I am using this to scroll to the footer view of a tableView:

[self.tableView scrollRectToVisible:[self.tableView convertRect:self.tableView.tableFooterView.bounds fromView:self.tableView.tableFooterView] animated:YES];

The best way to scroll a UITableView to the bottom of it's footerView is to simply set the content offset. You can calculate the bottom using the contentSize and the current bounds

Here is the way I do it.

CGPoint newContentOffset = CGPointMake(0, [self.instanceOfATableView contentSize].height -  self.instanceOfATableView.bounds.size.height);

[self.instanceOfATableView setContentOffset:newContentOffset animated:YES]; 

Thanks to iphone_developer here is what I did:

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[tableView numberOfRowsInSection:0]-1 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];

Then while I'm adding rows, I'm calling this and my tableView's footer view keeps being visible

Swift Version:

tableView.scrollToRow(at: IndexPath(row: self.tblview.numberOfRows(inSection: 0) - 1, section: 0), at: .top, animated: true)

So many poor answers. :-)

The BEST way:

[self.tableView scrollRectToVisible:
     self.tableView.tableFooterView.frame animated:YES
];

Maybe something like:

[tableView setContentOffset:CGPointMake(0, tableView.contentSize.height) animated:YES];

Since UITableView is a subclass of UIScrollView, you can scroll to wherever you like using the UIScrollView method

- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated

Just set the rect so that when it's visible the footer is visible, and you'll have your solution (you can use the footer's rect or something else, just so long as you get the right behavior all the time).

My late answer is for developer, who need to show footer when the keyboard is shown. The right solution is to consider contentInset property (which can be changed after keyboard is shown), so it's super easy:

- (void)scrollToFooter {
  UIEdgeInsets tableInsets = self.tableView.contentInset;
  CGFloat tableHeight = self.tableView.frame.size.height - tableInsets.bottom - tableInsets.top;
  CGFloat bottom = CGRectGetMaxY(self.tableView.tableFooterView.frame);
  CGFloat offset = bottom - tableHeight;
  if(offset > 0.f) {
    [self.tableView setContentOffset:CGPointMake(0,  offset) animated:YES];
  }
}

I must notice, that in my case tableView was added to my own ViewController and one of cells have UITextField which become first responder. To move show footer when keyboard is shown you need to register keyboard did shown notification and (on iOS7) perform this method in the end of current run loop, coz in this case iOS7 automatically perform scrollToRowAtIndexPath after our method and footer will not be shown.

-(void)registerKeyboardNotification {
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(keyboardDidShown:)
                                               name:UIKeyboardDidShowNotification object:nil];
}

- (void)keyboardDidShown:(id)notification {
  //move to the end of run loop
  [self performSelector:@selector(scrollToFooter) withObject:nil afterDelay:.0];
}

The easiest way to do this is to use UITableViewScrollPositionTop on the LAST ROW in the LAST SECTION. This works very well for me...

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:LAST_ROW inSection:LAST_SECTION] atScrollPosition:UITableViewScrollPositionTop animated:YES];

Make sure your Table Footer View is well spaced out at the bottom and it should sit nicely animated inside the view...

Hope this helps...

This good work for me!

CGRect footerBounds = [addCommentContainer bounds];
CGRect footerRectInTable = [tableview convertRect:footerBounds fromView:addCommentContainer];
[tableview scrollRectToVisible:footerRectInTable animated:YES];

This works for me in Swift 4

func addRow() {
    tableView.beginUpdates()
    tableView.insertRows(at: [IndexPath(row: array.count - 1, section: 0)], with: .automatic)
    tableView.endUpdates()

    DispatchQueue.main.async {
        self.scrollToBottom()
    }
}

func scrollToBottom() {
    let footerBounds = tableView.tableFooterView?.bounds
    let footerRectInTable = tableView.convert(footerBounds!, from: tableView.tableFooterView!)
    tableView.scrollRectToVisible(footerRectInTable, animated: true)
}

Great idea, was looking for this myself:) Here's sample code, which would do the trick:

[tableView reloadData];
NSIndexPath *index = [NSIndexPath indexPathForRow:0 inSection:1];
[tableView scrollToRowAtIndexPath:index
    atScrollPosition:UITableViewScrollPositionBottom animated:YES];

You MUST have at least one cell in your tableView footer, the problem is that it's going to visible. Didn't have time to test, but I'd guess you could make it really small?

Additionally you must implement correct stuff inside numberOfSectionsInTableView (at least one for table and one for footer), numberOfRowsInSection (at least one for footer, your last section), viewForHeaderInSection (nil except for your cell), heightForHeaderInSection (maybe if you set this as zero), cellForRowAtIndexPath (add special case for your cell in footer)...

That should be enough.

This work to me:

- (void)tableViewScrollToBottomAnimated:(BOOL)animated {
    NSInteger numberOfRows = [self.tableView numberOfRowsInSection:0];
    if (numberOfRows) {
        if (self.tableView.tableFooterView) {
            [self.tableView scrollRectToVisible:
             self.tableView.tableFooterView.frame animated:YES
             ];
        } else {
            [self.tableView scrollToRowAtIndexPath:
             [NSIndexPath indexPathForRow:numberOfRows-1 inSection:0]
                                  atScrollPosition:UITableViewScrollPositionBottom
                                          animated:animated
             ];
        }
    }
}

I'm using this:

- (void)scrollToBottom{
   [self.myTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.fetchedResultsController.fetchedObjects count] -1 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];

}

I haven't tried, but what happens when you scroll to the last row+1?

Another idea would be to always add a dummy entry at the end and make it have a different look so it's seen as a footer. Then you can always scroll to that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM