如何将UITableView滚动到tableFooterView

时间:2022-08-25 07:52:40

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

我有一个UITableView,它的内容是动态变化的,比如FIFO堆栈。细胞被添加到底部并从顶部移除。

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).

这样做的效果很好,我可以滚动到indexPath,这样,最新的消息总是向下滚动到底部(就像聊天应用程序一样)。

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

现在. .我想在表格部分添加一个页脚。而不是使用

SrollToRowAtIndexPath

SrollToRowAtIndexPath

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

我希望能够滚动到tableFooterView。

Any ideas how I can do that would be appreciated.

我能做的任何想法都将受到感激。

14 个解决方案

#1


27  

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];

#2


27  

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

滚动UITableView到它的footerView底部的最佳方法是简单地设置内容偏移量。您可以使用内容大小和当前边界计算底部

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]; 

#3


13  

Thanks to iphone_developer here is what I did :

感谢iphone_developer,这就是我所做的:

[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

当我添加行时,我调用这个,我的tableView的页脚视图保持可见

#4


12  

So many poor answers. :-)

所以许多贫穷的答案。:-)

The BEST way:

最好的方法:

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

#5


4  

Maybe something like:

也许类似:

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

#6


3  

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

由于UITableView是UIScrollView的子类,您可以使用UIScrollView方法滚动到您喜欢的任何地方

- (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).

只需设置rect,以便当它可见时,页脚是可见的,您将得到您的解决方案(您可以使用页脚的rect或其他东西,只要您始终得到正确的行为)。

#7


2  

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:

我最近的回答是针对开发人员的,他们需要在显示键盘时显示页脚。正确的解决方案是考虑contentInset属性(可以在显示键盘后进行更改),因此非常简单:

- (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.

我必须注意到,在我的例子中tableView被添加到我自己的ViewController中其中一个单元格有UITextField成为了第一个responder。要在显示键盘时移动显示页脚,您需要注册键盘did show notification和(在iOS7上)在当前运行循环结束时执行此方法,因为在这种情况下,iOS7在我们的方法和页脚没有显示之后会自动执行scrollToRowAtIndexPath。

-(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];
}

#8


1  

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

最简单的方法是在最后一节的最后一行使用UITableViewScrollPositionTop。这对我很有效……

[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...

希望这有助于……

#9


1  

This good work for me!

这对我来说是个好工作!

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

#10


0  

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?

在tableView页脚中必须至少有一个单元格,问题是它是可见的。没有时间测试,但我猜你可以把它做得很小?

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)...

此外,您必须在numberOfSectionsInTableView(表至少一个,页脚至少一个)、numberOfRowsInSection(页脚至少一个,最后一节)、viewForHeaderInSection(单元格除外)、heightForHeaderInSection(如果您将其设置为零)、cellForRowAtIndexPath(添加特殊情况)中…

That should be enough.

这应该足够了。

#11


0  

I'm using this:

我用这个:

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

}

}

#12


0  

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
             ];
        }
    }
}

#13


0  

This works for me in Swift 4

这在《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)
}

#14


-4  

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

我还没试过,但是当你滚动到最后一行+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.

另一个想法是,在最后添加一个虚拟条目,使它有一个不同的外观,因此它被视为一个页脚。然后你可以滚动到那个。

#1


27  

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];

#2


27  

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

滚动UITableView到它的footerView底部的最佳方法是简单地设置内容偏移量。您可以使用内容大小和当前边界计算底部

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]; 

#3


13  

Thanks to iphone_developer here is what I did :

感谢iphone_developer,这就是我所做的:

[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

当我添加行时,我调用这个,我的tableView的页脚视图保持可见

#4


12  

So many poor answers. :-)

所以许多贫穷的答案。:-)

The BEST way:

最好的方法:

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

#5


4  

Maybe something like:

也许类似:

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

#6


3  

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

由于UITableView是UIScrollView的子类,您可以使用UIScrollView方法滚动到您喜欢的任何地方

- (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).

只需设置rect,以便当它可见时,页脚是可见的,您将得到您的解决方案(您可以使用页脚的rect或其他东西,只要您始终得到正确的行为)。

#7


2  

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:

我最近的回答是针对开发人员的,他们需要在显示键盘时显示页脚。正确的解决方案是考虑contentInset属性(可以在显示键盘后进行更改),因此非常简单:

- (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.

我必须注意到,在我的例子中tableView被添加到我自己的ViewController中其中一个单元格有UITextField成为了第一个responder。要在显示键盘时移动显示页脚,您需要注册键盘did show notification和(在iOS7上)在当前运行循环结束时执行此方法,因为在这种情况下,iOS7在我们的方法和页脚没有显示之后会自动执行scrollToRowAtIndexPath。

-(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];
}

#8


1  

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

最简单的方法是在最后一节的最后一行使用UITableViewScrollPositionTop。这对我很有效……

[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...

希望这有助于……

#9


1  

This good work for me!

这对我来说是个好工作!

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

#10


0  

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?

在tableView页脚中必须至少有一个单元格,问题是它是可见的。没有时间测试,但我猜你可以把它做得很小?

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)...

此外,您必须在numberOfSectionsInTableView(表至少一个,页脚至少一个)、numberOfRowsInSection(页脚至少一个,最后一节)、viewForHeaderInSection(单元格除外)、heightForHeaderInSection(如果您将其设置为零)、cellForRowAtIndexPath(添加特殊情况)中…

That should be enough.

这应该足够了。

#11


0  

I'm using this:

我用这个:

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

}

}

#12


0  

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
             ];
        }
    }
}

#13


0  

This works for me in Swift 4

这在《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)
}

#14


-4  

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

我还没试过,但是当你滚动到最后一行+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.

另一个想法是,在最后添加一个虚拟条目,使它有一个不同的外观,因此它被视为一个页脚。然后你可以滚动到那个。